Part Number: DRA722
Tool/software: Linux
I have been struggling for weeks trying to get GPIO interrupts to work on the IPU (using TI-RTOS and the PDK GPIO driver). I've just now gotten it to work with the following code (non-relevant portions omitted for brevity):
GPIO_v1_hwAttrs_list GPIO_v1_hwAttrs = { ... { (CSL_IPU_GPIO5_REGS + Du32Ipu_IOMMU_Offset), 49, 0, CSL_XBAR_GPIO5_IRQ_1, 0 }, ... }; #define GPIO_RX0BF_CAN3_PIN (0x0500) // gpio5_0 #define GPIO_RX1BF_CAN3_PIN (0x0501) // gpio5_1 GPIO_PinConfig gpioPinConfigs[GPIO_PIN_COUNT] = { ... GPIO_RX0BF_CAN3_PIN | GPIO_CFG_IN_INT_LOW | GPIO_CFG_INPUT, GPIO_RX1BF_CAN3_PIN | GPIO_CFG_IN_INT_LOW | GPIO_CFG_INPUT, ... }; GPIO_CallbackFxn gpioCallbackFunctions[] = { ... ExtCanDrv__Can3RXnBF_Isr, // GPIO_RX0BF_CAN3 ExtCanDrv__Can3RXnBF_Isr, // GPIO_RX1BF_CAN3 ... }; GPIO_v1_Config GPIO_v1_config = { gpioPinConfigs, gpioCallbackFunctions, sizeof(gpioPinConfigs) / sizeof(GPIO_PinConfig), sizeof(gpioCallbackFunctions) / sizeof(GPIO_CallbackFxn), 0x20, };
from my main() function, before the call to BIOS_start(), I call the following function:
void vGpioDrv_eInitialize(void) { CSL_l4per_cm_core_componentRegs *l4PerCmReg = (CSL_l4per_cm_core_componentRegs *)(CSL_MPU_L4PER_CM_CORE_REGS + Du32Ipu_IOMMU_Offset); ... CSL_FINST(l4PerCmReg->CM_L4PER_GPIO5_CLKCTRL_REG, L4PER_CM_CORE_COMPONENT_CM_L4PER_GPIO5_CLKCTRL_REG_MODULEMODE, AUTO); l4PerCmReg->CM_L4PER_GPIO5_CLKCTRL_REG |= ( (CM_L4PER_GPIO5_CLKCTRL_OPTFCLKEN_DBCLK_FCLK_EN << CM_L4PER_GPIO5_CLKCTRL_OPTFCLKEN_DBCLK_SHIFT) | (CM_L4PER_GPIO5_CLKCTRL_MODULEMODE_AUTO << CM_L4PER_GPIO5_CLKCTRL_MODULEMODE_SHIFT) ); ... // RX0BF_CAN3_PIN - gpio5_0 TU32 ulAddress = (SOC_CORE_PAD_IO_REGISTERS_BASE + Du32Ipu_IOMMU_Offset + CSL_CONTROL_CORE_PAD_IO_PAD_MCASP1_ACLKR); // 0x6A0036AC TU32 ulData = (SLEW_CONTROL_SLOW | (((uint32_t) 6) << GPIO_CFG_IO_LSB) | CTRL_CORE_PAD_MUXMODE_GPIO); // 0x000E000E HW_WR_REG32(ulAddress, ulData); // RX1BF_CAN3_PIN - gpio5_1 ulAddress = (SOC_CORE_PAD_IO_REGISTERS_BASE + Du32Ipu_IOMMU_Offset + CSL_CONTROL_CORE_PAD_IO_PAD_MCASP1_FSR); // 0x6A0036B0 ulData = (SLEW_CONTROL_SLOW | (((uint32_t) 6) << GPIO_CFG_IO_LSB) | CTRL_CORE_PAD_MUXMODE_GPIO); // 0x000E000E HW_WR_REG32(ulAddress, ulData); ... GPIO_init(); IntXbar_connectIRQ(49, CSL_XBAR_GPIO5_IRQ_1); GPIO_enableInt(GPIO_RX0BF_CAN3); GPIO_enableInt(GPIO_RX1BF_CAN3); }
After this, my ISR is called when an interrupt is received, so it looks like things are working well on the IPU. However, when the system boots, I get the following error on the Linux console:
[ 17.206769] irq 168, desc: ef1d0d80, depth: 1, count: 0, unhandled: 0
[ 17.213246] ->handle_irq(): c00810e8, handle_bad_irq+0x0/0x280
[ 17.219204] ->irq_data.chip(): ef1d0c10, 0xef1d0c10
[ 17.224106] ->action(): (null)
[ 17.227342] IRQ_NOPROBE set
[ 17.230403] unexpected IRQ trap at vector a8
I can see the following interrupts by typing cat /proc/interrupts
:
CPU0
16: 0 CBAR 32 Level gp_timer
17: 0 GIC 29 Edge arch_timer
18: 392273 GIC 30 Edge arch_timer
22: 0 CBAR 4 Level l3-dbg-irq
23: 0 WUGEN 10 Level l3-app-irq
25: 1 CBAR 121 Level talert
27: 55 CBAR 8 Level omap-dma-engine
30: 5072 CBAR 361 Level 43300000.edma_ccint
32: 1 CBAR 359 Level 43300000.edma_ccerrint
35: 0 CBAR 24 Level 4ae10000.gpio
68: 0 CBAR 25 Level 48055000.gpio
101: 0 CBAR 26 Level 48057000.gpio
134: 1119903 CBAR 27 Level 48059000.gpio
139: 1119903 48059000.gpio 4 Level egalax_i2c
167: 1 CBAR 28 Level 4805b000.gpio
168: 1 4805b000.gpio 0 Edge
200: 0 CBAR 29 Level 4805d000.gpio
233: 0 CBAR 30 Level 48051000.gpio
266: 0 CBAR 116 Level 48053000.gpio
299: 4595 CBAR 67 Level 4806a000.serial
301: 401 CBAR 69 Level 48020000.serial
302: 0 CBAR 100 Level 48066000.serial
306: 20332 CBAR 251 Level mbox_ipu1_ipc3x
310: 32 CBAR 255 Level mbox_ipu2_ipc3x
328: 11 CBAR 108 Level omap_dmm_irq_handler
329: 26233 CBAR 16 Level SGX ISR
331: 379 CBAR 51 Level 48070000.i2c
332: 1215 CBAR 56 Level 48060000.i2c
333: 0 CBAR 57 Level 4807a000.i2c
334: 13 CBAR 78 Level mmc0
335: 4977 CBAR 81 Level mmc1
336: 0 CBAR 395 Level 58882000.mmu
337: 0 CBAR 396 Level 55082000.mmu
341: 5 CBAR 72 Level dwc3-omap
342: 5 CBAR 87 Level dwc3-omap
347: 20 CBAR 46 Level 4b101000.sham
348: 0 CBAR 47 Level 48090000.rng
350: 7542 CBAR 20 Level OMAP DISPC
415: 0 CBAR 2 Edge tps65917
416: 0 pinctrl 584 Edge 48020000.serial
417: 3416 CBAR 71 Level xhci-hcd:usb1
418: 0 CBAR 73 Level xhci-hcd:usb3
IPI0: 0 CPU wakeup interrupts
IPI1: 0 Timer broadcast interrupts
IPI2: 0 Rescheduling interrupts
IPI3: 0 Function call interrupts
IPI4: 0 Single function call interrupts
IPI5: 0 CPU stop interrupts
IPI6: 0 IRQ work interrupts
IPI7: 0 completion interrupts
Err: 1
If I don't run the above IPU code, then interrupt 168 does not exist, and I get no errors on the console. It appears that configuring the interrupt on the IPU is somehow also creating an interrupt on the MPU, but one with no handler. Any ideas?
Thanks,
Mike