-
Notifications
You must be signed in to change notification settings - Fork 7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
soc: renesas: ra: add interrupt map support for RA2A1 #84427
soc: renesas: ra: add interrupt map support for RA2A1 #84427
Conversation
thenguyenyf
commented
Jan 23, 2025
- Renesas RA has a dynamic interrupt mechanism consisting of m hardware interrupt events and n NVIC interrupt lines. At one time, just 1 hardware interrupt event can be routed to 1 NVIC line. The interrupt event was routed to NVIC controller with a m:n map by the Interrupt Controller Unit HWIP.
- This PR to add a partial support for interrupt event route to NVIC controller, by the Devicetree Interrupt mapping feature: https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#interrupts-and-interrupt-mapping
- First target is RA2A1 MCU and the ek_ra2a1 board.
This commit to support route the ICU signal to NVIC controller for RA2A1 Signed-off-by: The Nguyen <[email protected]>
Would it not be simpler to just have one interrupt map, mapping from the ICU domain to the NVIC domain? If a device is not used, it has no interrupts defined:
then, if a user needs said device, set the status and define the IRQs
I'm missing what these nodes are useful for: |
Hi @bjarki-andreasen , nice to see you!
→ The big one interrupt map, that map all interrupt sources as default for enabled node, will have a NG point when someone would like to enable other node (etc. by an overlay file). They should redefine whole interrupt map, not only the interrupt map for their additional node, but also the default node - which should be handled before. So, I split the big map into many sub-units, then the user can modify a part but not necessary to overwrite the already mapped event.
→ In my opinion, it is NG for user experience. The interrupts should be defined correctly: number of interrupts, the interrupts name, ..., because it is mandatory for driver functionality. It is very hard for user to investigate how to add the correct interrupt information for each shim driver. Currently, we are doing as your idea (not add interrupt prop for disabled node) to work around with the problem of not having enough NVIC interrupt lines, and the fact is, there is some feedback/question about how they can look up the information to add interrupt information for disabled node (in overlay or in their custom board dts). |
Interrupt maps are not mutable, they should not be changed by an overlay. Interrupt maps contain every possible routing of any interrupt line between domains, this is restricted to physical hardware, in this case, which ICU event can be routed to which NVIC interrupt line.
Users have the option of looking to the interrupt map or reference manual to understand how interrupts can be routed. The devicetree is not a manual, its a description of hardware.
Currently, this PR is working around the way interrupt maps work, which is not exactly user friendly for users who understand how interrupt maps work... I would have, and still have no clue how to use the novel approach to interrupt mapping presented in this PR, and that will apply to other users as well. Please look to the devicetree specification, v0.4, section 2.4.4 Interrupt maps are well documented. This PR is deviating from the spec, which will leave users confused. If the hardware is complex, like the ICU inherently is, then the interrupt map will be complex. Its not a problem with the spec, it perfectly models the ICU, the problem seems to be an unwillingness to accurately model the hardware as is. |
Let me summarize some points as my understanding, please correct me if there are any wrong:
|
So, I'm afraid interrupt-map doesn't really solve my problem
|
That I believe is correct.
Yes, interrupt maps only contain possible mappings...
This is not correct. The interrupt-map is not optional. If interrupts are physically connected between two or more domains, all possible physical connections are defined in an interrupt map, and the subset of interrupts to connect are defined by devices which select the interrupts to connect their "events"/irq lines to in their domain (ICU domain in this case), which is then looked up in the interrupt-map to figure out which interrupt controller it routes to in any parent domain (NVIC in this case). To step back a bit, the reason we use interrupt maps, is quite simply because it is a user choice, and I really want to emphasize: "user choice" here, which, if any, device event is actually routed to an interrupt line. Device drivers can be written to be entirely polling in most cases, not using any interrupts which any hardware provides. Interrupts are an optional feature, which can be used for async hardware usage, if the user so desires. Think of a flash controller for example, it could have an interrupt line which triggers when its done erasing a page, a driver could choose to use this interrupt to wait, or it could just spin, checking a flag which is set when its done. This is the case for most hardware. When one uses a platform where there are more events/interrupts than there are interrupt lines available to the CPU, as mentioned here as well
the user must prioritize which hardware event should be routed to an interrupt, and which can simply be polled. There is no algorithm to choose this, its a user choice. The interrupt map makes this selection possible, along with the user being able to specify on a per device level which event to actually connect to which interrupt line, if any. The interrupt-map, despite what you claim, does indeed solve the problem as good as I believe possible. It provides every possible interrupt configuration, which the user can then select from. Its a complex problem, with a complimentarily complex solution. It being "complex" in itself is not an argument, unless the complexity of the interrupt-map itself was more complex than the ICU to NVIC mapping, which it is not IMO, its near identical in complexity. |
I'm still wondering about 2 points:
|
Unless that someone also changes what SoC they are using, the interrupt-map will remain unchanged :) The interrupt-map is a lookup table, it contains only possibilities, not decisions.
Devicetree bindings, the .yaml files in When creating a board, define a subset of peripherals in a viable manner, which users can use for reference. Like an instance of a uart where you connect its interrupts. The user may need to change the interrupts or disable the peripheral in their overlays later, that is expected. |
It sounds good.
Maybe I missed something. Do you mean the interrupt map can be defined as below (map the sci0 and spi0 to NVIC slot 0-7 as their possibilities)? &icu {
interrupt-map = <
/* sci0 interrupts variant 1*/
0 RA_ICU_EVENT_SCI0_RXI &nvic 0 0 1 /* NVIC: IRQn = 0, IPL = 1 */
0 RA_ICU_EVENT_SCI0_TXI &nvic 0 1 1 /* NVIC: IRQn = 1, IPL = 1 */
0 RA_ICU_EVENT_SCI0_TEI &nvic 0 2 1 /* NVIC: IRQn = 2, IPL = 1 */
0 RA_ICU_EVENT_SCI0_ERI &nvic 0 3 1 /* NVIC: IRQn = 3, IPL = 1 */
/* sci0 interrupts variant 2*/
0 RA_ICU_EVENT_SCI0_RXI &nvic 0 4 1 /* NVIC: IRQn = 4, IPL = 1 */
0 RA_ICU_EVENT_SCI0_TXI &nvic 0 5 1 /* NVIC: IRQn = 5, IPL = 1 */
0 RA_ICU_EVENT_SCI0_TEI &nvic 0 6 1 /* NVIC: IRQn = 6, IPL = 1 */
0 RA_ICU_EVENT_SCI0_ERI &nvic 0 7 1 /* NVIC: IRQn = 7, IPL = 1 */
/* spi1 interrupt variant 1 */
0 RA_ICU_EVENT_SPI1_RXI &nvic 0 0 1 /* NVIC: IRQn = 0, IPL = 1 */
0 RA_ICU_EVENT_SPI1_TXI &nvic 0 1 1 /* NVIC: IRQn = 1, IPL = 1 */
0 RA_ICU_EVENT_SPI1_TEI &nvic 0 2 1 /* NVIC: IRQn = 2, IPL = 1 */
0 RA_ICU_EVENT_SPI1_ERI &nvic 0 3 1 /* NVIC: IRQn = 3, IPL = 1 */
/* spi1 interrupt variant 2 */
0 RA_ICU_EVENT_SPI1_RXI &nvic 0 4 1 /* NVIC: IRQn = 4, IPL = 1 */
0 RA_ICU_EVENT_SPI1_TXI &nvic 0 5 1 /* NVIC: IRQn = 5, IPL = 1 */
0 RA_ICU_EVENT_SPI1_TEI &nvic 0 6 1 /* NVIC: IRQn = 6, IPL = 1 */
0 RA_ICU_EVENT_SPI1_ERI &nvic 0 7 1 /* NVIC: IRQn = 7, IPL = 1 */
>;
}; I received a build error for multiple registration at an ISR slot. Because the ICU doesn't allow shared interrupt, let's take example with RA8M1 (have 296 ICU events and 96 NVIC lines) we can only map 96 events to 96 NVIC line. So, if user want to use a disabled device node (define in SoC dtsi but not enabled by default in board dts), they should remove/disabled some device node, then map its ICU event to the removed device node NVIC slots, right? And I think it's a common usage, because I see the samples/ztests overlays to enable a device node that not used by the board dts everywhere. |
The interrupt-map is erroneous, the child specifiers have to be unique:
and
have identical child specifiers, so dts can not determine which to select. You need to add more child specifiers to distinguish which event "group" you use. Have you seen #75946? See this comment for a viable interrupt map: #75946 (comment) |
Okay. Let's me investigate on what we have discussed. Thanks for your help! |