(source pg 4195 of TRM AM57x) The individual connection between all module IRQs and all
IRQ_CROSSBAR inputs is shown in Section 17.3.12 (Which we have already observed and the image is pasted down below, where we can see corssbar –> MCASP), Mapping of Device Interrupts to
IRQ_CROSSBAR Inputs of Chapter 17, Interrupt Controllers.
In addition, the
CTRL_CORE_OVS_IRQ_IO_MUX register is used to select for observation on two external pads any IRQ connected to the
IRQ_CROSSBAR inputs. Using the
OVS_IRQ_IO_MUX_2 bit field all IRQs can be mapped to the
obs_irq2 signal. The
CTRL_CORE_OVS_IRQ_IO_MUX[8:0] OVS_IRQ_IO_MUX_1 bit field maps all IRQs to the
obs_irq1 signal. For example, setting the
CTRL_CORE_OVS_IRQ_IO_MUX[8:0] OVS_IRQ_IO_MUX_1 to 0x18 maps the
GPIO1_IRQ_1 to the obs_irq1 line and thus this IRQ can be observed.
So, infering from what has been said above, we will try to do the following:
OVS_IRQ_IO_MUX_1at bits 8:0
2at bits 17:9 .
IRQ_CROSSBAR_103which is in hex
devmem2tool to try and set these in the required bits. (note: a word is 16 bits). Once that's done we expect to to have the bit fields mapped to
CTRL_CORE_PRUSS1_IRQ_38_39and set the bits 8:0 ie.
PRUSS1_IRQ_38and 24:16 ie.
The MII_RT Event Enable Register enables MII_RT mode events to the PRUSS.PRUSS_INTC.
PRUSS_MII_RT register at address
0x4B22 602C. (Note set the
MII_RT_EVENT_EN=0b1) to have
PRU-ICSS MII_RT module associated events, mapped to the same lines.
In our case, these will be
38 IRQ input lines.
Now, referring to
The channel map registers (PRUSS_INTC_CMRi, where i=0 to 15) define the channel for each system interrupt.
and to understand system interrupt, referring to
Enable required system interrupts: System interrupts that are required to get propagated to host are to be enabled individually by writing to INDEX field in the system interrupt enable indexed set register (
PRUSS_INTC_EISR). The interrupt to enable is the index value written. This sets the Enable Register bit of the given index.
which means that we need to write
0x4B22 0028 inorder to enable those two interrupts one by one.
It is pobably worth reading the "The next stage is to capture which system interrupts are pending." part, which I am not sure, but think it has been done already in the BELA Pru irq code.
Now, we come to
PRUSS_INTC_CMRi registers located at
0x4B22N 0400 + 0X4*i, where i in our case will be channel i=1.
So, we want the system interrupt
0x26 and 27 to be mapped to channel 1 which when divided by 4 means that we write the value of k as
0x9 to the bits
Now that we have mapped the right McASP interrupts to channel 1, which is what the existing BELA PRU IRQ Code checks for already, I think so that the above described workflow should be enough.
The PRU-ICSS interrupt controller (
PRUSS_INTC) maps interrupts coming from different parts of the device (mapped to PRU-ICSS1/PRU-ICSS2 via the device
IRQ_CROSSBAR) to a reduced set of PRU-ICSS interrupt channels. The
PRUSS_INTC has the following features:
220.127.116.11 PRU-ICSS Interrupt Controller Functional Description The PRU-ICSS incorporates an interrupt controller -
PRUSS_INTC that supports up to 64 system interrupts from different peripherals (including 32 interrupts from PRU-ICSS located interrupt sources). The
PRUSS_INTC maps these system events to 10 channels inside the
PRUSS_INTC (see Figure).
Interrupts from these 10 channels are further mapped to 10 Host Interrupts.
The next stage of
PRUSS_INTC is to enable system interrupts based on programmed settings. The following sequence is to be followed to enable interrupts:
|0x4B22 0028|| |
|0x4B2A 0028|| |
Table 30-741. PRUSS1_INTC Registers Mapping Summary
|0x4B22 0284|| |
|0x4B2A 0284|| |
PRUSS_INTC_SECR1 talks in detail about the same.
PRUSS_INTC_HIEISR), enable the required host interrupts. The host interrupt to enable is the index value written. This enables the host interrupt output or triggers the output again if that host interrupt is already enabled. ref. Table 30-231. PRUSS_INTC_HIEISR
|0x4B22 0034|| |
|0x4B2A 0034|| |
PRUSS_INTC_GER) to 1, all host interrupts will be enabled. Individual host interrupts are still enabled or disabled from their individual enables and are not overridden by the global enable. (we probably do not need this)
Note: Checkout 18.104.22.168.2.2 PRU-ICSS Interrupt Status Checking of AM57xx Manual, just to be sure that the BELA PRU code is using the right register locations to check the interrupt statuses.
Follow these steps to configure the interrupt controller.
Set polarity and type of system event through the System Interrupt Polarity Registers (
PRUSS_INTC_SIPR0) and the System Interrupt Type Registers (
PRUSS_INTC_SITR0). Polarity of all system interrupts is always high. Type of all system interrupts is always pulse.
PRUSS_INTC_CMRi(i=0 to 15) channel mapping registers.
PRUSS_INTC_HMR0/1/2registers. Recommended channel "x" to be mapped to host interrupt "x".
PRUSS_INTC_CMR0 and 1. As per Table 30-781
PRUSS_INTC_CMRi the physical addresses will be:
0x4B22 0400 + 0 –> for
0x4B2A 0400 + 4 = 0x4B2A0404 –>
and then we have to set the bits according to this table: Here, we will set the bits 3:0 ie.
MCASPi_IRQ_AREVTcan be also generated if the
RDATAinterrupt is enabled in the
MCASP_EVTCTLRregister (for details, see Section 22.214.171.124.1, Receive Data Ready Interrupt).
From table 17-11. PRUSS1_INTC Default Interrupt Mapping (continued) Let's use the
PRUSS1_IRQ_38 which is
Reserved by default but can be remapped to a valid interrupt source and also
PRUSS1_IRQ_39. From pg 43821 Table 18-553,
0x0000 08D4 Physical Address:
The basic unit of communication between remoteproc and the PRU as of now is using downcalls and syscalls.
A syscall is when the PRU raises an IRQ and halts itself, storing some values in its registers. The kernel module handles the syscall IRQ, it reads the registers, manipulates them and resumes the PRU over the HALT instruction. See here for an example code of the syscall on the PRU side.
A downcall is initiated by the kernel module. Think of it as calling a function in the PRU from the kernel module and receiving the return value back in the kernel module.
Note: The PRU has to be polling for the downcall, and it acknowledges with a special syscall. Then the function
handle_downcall is called, which receives the downcall value and the parameters. So the
handle_downcall example is a switch-case thing where the PRU does something and once it returns from this function, there is a syscall triggered which signals that the downcall is complete, the kernel module reads the return value of the function, after which the downcalling function in the kernel module returns with the return value.
the crux is that remoteproc currently is very application-specific and you have to twist and adapt the kernel module to your needs. Once the remoteproc stuff gets finalized, ideally there would be a generic framework and userspace layer on top of the driver to allow you to write your own applications from userspace, in a similar way as it is currently done using libprussdrv.
CTRL_CORE_PRUSS1_IRQ_32_33 RW 32 0x0000 08C8 0x4A00 28C8