Lines Matching +full:multi +full:- +full:channel

4  * SPDX-License-Identifier: Apache-2.0
16 * - in Zephyr terminology, the IRQ_STEER can be considered an interrupt aggregator. As such,
20 * - below you may find a diagram meant to give you an intuition regarding the IP's structure
26 * MASK[0:4]------ |
28 * +------+
32 * +------+
34 * SET[0:4]------ |
36 * +------+
40 * +------+
43 * +------+
47 * +------+
56 * +------+
58 * | AND | ---------- MINTDIS[0:2]
60 * +------+
66 * - initially, all SYSTEM_INTID are grouped by 32 => 5 groups.
88 * - whenever a SYSTEM_INTID is asserted, its corresponding MASTER_OUT signal will also
91 * > please note the difference between an IRQ_STEER channel and an IRQ_STEER master output.
92 * An IRQ_STEER channel refers to an IRQ_STEER instance (e.g: the DSP uses IRQ_STEER channel
93 * 0 a.k.a instance 0). An IRQ_STEER channel has multiple master outputs. For example, in
94 * the case of i.MX8MP each IRQ_STEER channel has 3 master outputs since an IRQ_STEER channel
98 * 3) Using Zephyr's multi-level interrupt support
99 * - since Zephyr supports organizing interrupts on multiple levels, we can use this to
102 * - these are the interrupts that go directly to the processor (for example,
106 * - these interrupts go through IRQ_STEER and are signaled by a single
108 * - e.g: for i.MX8MP, INTID 34 (SDMA3) goes through IRQ_STEER and is signaled
111 * - the following diagram (1) shows the interrupt organization on i.MX8MP:
112 * +------------+
114 * SYSTEM_INTID[31:0] ------ IRQ_STEER_MASTER_0 ---- | 19 |
116 * SYSTEM_INTID[95:32] ----- IRQ_STEER_MASTER_1 ---- | 20 DSP |
118 * SYSTEM_INTID[159:96] ---- IRQ_STEER_MASTER_2 ---- | 21 |
120 * +------------+
122 * - as such, asserting a system interrupt will lead to asserting its corresponding DSP
126 * - in the above diagram, SYSTEM_INTID[x] are LEVEL 2 interrupts, while 19, 20, and 21 are
129 * - INTID 19 is the parent of SYSTEM_INTID[31:0] and so on.
134 * - these are the values that can be found in NXP's TRMs for different
136 * - for example, INTID 34 is a system INTID for SDMA3 (i.MX8MP).
139 * - these are the Zephyr-specific encodings of the system INTIDs.
140 * - these are used to encode multi-level interrupts (for more information
146 * - these are the encodings of the system INTIDs used in the DTS.
147 * - all of these INTIDs are relative to IRQ_STEER's MASTER_OUTs.
151 * - the following steps need to be performed:
170 * previous master - MASTER 0 - is in charge of aggregating
176 * RELATIVE_INTID(x) = x -
177 * \sum{i=0}^{y - 1} GET_MASTER_INT_NUM(i)
207 * - all of these steps are performed by to_zephyr_irq().
212 * - for this you just have to compute RELATIVE_INTID as described above in
214 * - for example, if an IP uses INTID 34 you'd write its interrupts property
219 * > PLEASE DON'T MISTAKE THE ZEPHYR MULTI-LEVEL INTERRUPT ORGANIZATION WITH THE XTENSA ONE.
222 …ttps://docs.zephyrproject.org/latest/kernel/services/interrupts.html#multi-level-interrupt-handling
266 (((const struct irqsteer_config *)disp->dev->config)->regmap_phys)
300 for (i = dispatcher->master_index - 1; i >= 0; i--) { in to_zephyr_irq()
301 idx -= IRQSTEER_GetMasterIrqCount(UINT_TO_IRQSTEER(regmap), i); in to_zephyr_irq()
304 return irq_to_level_2(idx) | dispatcher->irq; in to_zephyr_irq()
307 /* used to convert master-relative INTID to system INTID */
312 for (i = master_index - 1; i >= 0; i--) { in to_system_irq()
339 xtensa_irq_enable(XTENSA_IRQ_NUMBER(disp->irq)); in _irqstr_disp_enable_disable()
341 IRQSTEER_EnableMasterInterrupt(UINT_TO_IRQSTEER(regmap), disp->irq); in _irqstr_disp_enable_disable()
343 IRQSTEER_DisableMasterInterrupt(UINT_TO_IRQSTEER(regmap), disp->irq); in _irqstr_disp_enable_disable()
345 xtensa_irq_disable(XTENSA_IRQ_NUMBER(disp->irq)); in _irqstr_disp_enable_disable()
353 if (disp->refcnt == UINT8_MAX) { in _irqstr_disp_get_unlocked()
354 LOG_WRN("disp for irq %d reference count reached limit", disp->irq); in _irqstr_disp_get_unlocked()
358 if (!disp->refcnt) { in _irqstr_disp_get_unlocked()
359 ret = pm_device_runtime_get(disp->dev); in _irqstr_disp_get_unlocked()
368 disp->refcnt++; in _irqstr_disp_get_unlocked()
371 disp->irq, disp->refcnt); in _irqstr_disp_get_unlocked()
378 if (!disp->refcnt) { in _irqstr_disp_put_unlocked()
379 LOG_WRN("disp for irq %d already put", disp->irq); in _irqstr_disp_put_unlocked()
383 disp->refcnt--; in _irqstr_disp_put_unlocked()
385 if (!disp->refcnt) { in _irqstr_disp_put_unlocked()
388 ret = pm_device_runtime_put(disp->dev); in _irqstr_disp_put_unlocked()
396 disp->irq, disp->refcnt); in _irqstr_disp_put_unlocked()
415 zephyr_irq, disp->master_index); in irqstr_request_irq_unlocked()
418 if (disp->irq_refcnt[zephyr_irq]) { in irqstr_request_irq_unlocked()
424 if (disp->irq_refcnt[zephyr_irq] == UINT8_MAX) { in irqstr_request_irq_unlocked()
429 if (!disp->irq_refcnt[zephyr_irq]) { in irqstr_request_irq_unlocked()
434 disp->irq_refcnt[zephyr_irq]++; in irqstr_request_irq_unlocked()
437 system_irq, disp->irq_refcnt[zephyr_irq]); in irqstr_request_irq_unlocked()
444 zephyr_irq, disp->master_index); in irqstr_release_irq_unlocked()
446 if (!disp->irq_refcnt[zephyr_irq]) { in irqstr_release_irq_unlocked()
451 disp->irq_refcnt[zephyr_irq]--; in irqstr_release_irq_unlocked()
453 if (!disp->irq_refcnt[zephyr_irq]) { in irqstr_release_irq_unlocked()
459 system_irq, disp->irq_refcnt[zephyr_irq]); in irqstr_release_irq_unlocked()
529 cfg = dispatchers[i].dev->config; in z_soc_irq_is_enabled()
551 cfg = dispatcher->dev->config; in irqsteer_isr_dispatcher()
554 status = IRQSTEER_GetMasterInterruptsStatus(UINT_TO_IRQSTEER(cfg->regmap_phys), in irqsteer_isr_dispatcher()
555 dispatcher->master_index); in irqsteer_isr_dispatcher()
560 /* convert master-relative INTID to a system INTID */ in irqsteer_isr_dispatcher()
561 system_irq = to_system_irq(cfg->regmap_phys, i, in irqsteer_isr_dispatcher()
562 dispatcher->master_index); in irqsteer_isr_dispatcher()
565 zephyr_irq = to_zephyr_irq(cfg->regmap_phys, system_irq, dispatcher); in irqsteer_isr_dispatcher()
593 /* TODO: do we need to add support for MMU-based SoCs? */