(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 CTRL_CORE_OVS_IRQ_IO_MUX[17:9]
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:
CTRL_CORE_OVS_IRQ_IO_MUX
is at 0x4A00 2D50
location.OVS_IRQ_IO_MUX_1
at bits 8:0 2
at bits 17:9 .IRQ_CROSSBAR_103
which is in hex 0x67
IRQ_CROSSBAR_104
ie. 0x68
.devmem2
tool 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 obs_irq1
and obs_irq2
respectively.CTRL_CORE_X_IRQ_B_A
registers, specifically CTRL_CORE_PRUSS1_IRQ_38_39
and set the bits 8:0 ie. PRUSS1_IRQ_38
and 24:16 ie. PRUSS1_IRQ_39
to 0x67
and 0x68
respectively.The MII_RT Event Enable Register enables MII_RT mode events to the PRUSS.PRUSS_INTC.
ie. the 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 PRUSS1_IRQ_39
and 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 0x26
and 0x27
to 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 11:8
ie. CH_MAP_1
.
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:
30.1.6.2 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 | PRUSS1_INTC |
0x4B2A 0028 | PRUSS2_INTC |
Table 30-741. PRUSS1_INTC Registers Mapping Summary
0x4B22 0284 | PRUSS1_INTC Base addr |
0x4B2A 0284 | PRUSS2_INTC |
Table 30-771. 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 | PRUSS1_INTC |
0x4B2A 0034 | PRUSS2_INTC |
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 30.2.6.2.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_SIPR1
and PRUSS_INTC_SIPR0
) and the System Interrupt Type Registers (PRUSS_INTC_SITR1
and PRUSS_INTC_SITR0
). Polarity of all system interrupts is always high. Type of all system interrupts is always pulse.
PRUSS_INTC
channel through PRUSS_INTC_CMRi
(i=0 to 15) channel mapping registers.PRUSS_INTC_HMR0/1/2
registers. Recommended channel "x" to be mapped to host interrupt "x".PRUSS_INTC_SECR0/1
registers.PRUSS_INTC_HIEISR
register.PRUSS_INTC_GER[0] ENABLE_HINT_ANY
bit.Let's take PRUSS_INTC_CMR0 and 1
. As per Table 30-781 PRUSS_INTC_CMRi
the physical addresses will be:
0x4B22 0400 + 0 –> for ...CMR_0
0x4B2A 0400 + 4 = 0x4B2A0404 –> ...CMR_1
and then we have to set the bits according to this table: Here, we will set the bits 3:0 ie. CH_MAP_0
pg 6076:
MCASPi_IRQ_AREVT
can be also generated if theRDATA
interrupt is enabled in theMCASP_EVTCTLR
register (for details, see Section 24.6.4.12.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,
Addr offset: 0x0000 08D4
Physical Address: 0x4A00 28D4
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.
pg4163
CTRL_CORE_PRUSS1_IRQ_32_33 RW 32 0x0000 08C8 0x4A00 28C8