Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 367
Fixes for SOF with Zephyr on i.MX#4524
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
2ac781cfedcc4cc01772e86c66f7111a1e5File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -27,6 +27,21 @@ DECLARE_SOF_UUID("irq", irq_uuid, 0x1862d39a, 0x3a84, 0x4d64, | ||
| DECLARE_TR_CTX(irq_tr, SOF_UUID(irq_uuid), LOG_LEVEL_INFO); | ||
| /* For i.MX, when building SOF with Zephyr, we use wrapper.c, | ||
| * interrupt.c and interrupt-irqsteer.c which causes name | ||
| * collisions. | ||
| * In order to avoid this and make any second level interrupt | ||
| * handling go through interrupt-irqsteer.c define macros to | ||
| * rename the duplicated functions. | ||
| */ | ||
| #if defined(__ZEPHYR__) && defined(CONFIG_IMX) | ||
| #define interrupt_get_irq mux_interrupt_get_irq | ||
| #define interrupt_register mux_interrupt_register | ||
| #define interrupt_unregister mux_interrupt_unregister | ||
| #define interrupt_enable mux_interrupt_enable | ||
| #define interrupt_disable mux_interrupt_disable | ||
lgirdwood marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| #endif | ||
| static SHARED_DATA struct cascade_root cascade_root; | ||
| static int interrupt_register_internal(uint32_t irq, void (*handler)(void *arg), | ||
| @@ -361,8 +376,18 @@ static int interrupt_register_internal(uint32_t irq, void (*handler)(void *arg), | ||
| /* no parent means we are registering DSP internal IRQ */ | ||
| cascade = interrupt_get_parent(irq); | ||
| if (!cascade) | ||
| if (!cascade) { | ||
| #if defined(__ZEPHYR__) && defined(CONFIG_IMX) | ||
| /* undefine the macro so that interrupt_register() | ||
| * is resolved to the one from wrapper.c | ||
| */ | ||
| #undef interrupt_register | ||
| return interrupt_register(irq, handler, arg); | ||
| #else | ||
| return arch_interrupt_register(irq, handler, arg); | ||
| #endif | ||
| } | ||
| spin_lock_irq(&cascade->lock, flags); | ||
| ret = irq_register_child(cascade, irq, handler, arg, desc); | ||
| @@ -386,7 +411,16 @@ static void interrupt_unregister_internal(uint32_t irq, const void *arg, | ||
| /* no parent means we are unregistering DSP internal IRQ */ | ||
| cascade = interrupt_get_parent(irq); | ||
| if (!cascade) { | ||
| #if defined(__ZEPHYR__) && defined(CONFIG_IMX) | ||
| /* undefine the macro so that interrupt_unregister() | ||
| * is resolved to the one from wrapper.c | ||
| */ | ||
| #undef interrupt_unregister | ||
| interrupt_unregister(irq, arg); | ||
| #else | ||
| arch_interrupt_unregister(irq); | ||
| #endif | ||
| return; | ||
| } | ||
| @@ -404,7 +438,16 @@ uint32_t interrupt_enable(uint32_t irq, void *arg) | ||
| if (cascade) | ||
| return irq_enable_child(cascade, irq, arg); | ||
| #if defined(__ZEPHYR__) && defined(CONFIG_IMX) | ||
| /* undefine the macro so that interrupt_enable() | ||
| * is resolved to the one from wrapper.c | ||
| */ | ||
| #undef interrupt_enable | ||
| return interrupt_enable(irq, arg); | ||
| #else | ||
| return arch_interrupt_enable_mask(1 << irq); | ||
| #endif | ||
| } | ||
| uint32_t interrupt_disable(uint32_t irq, void *arg) | ||
| @@ -416,5 +459,14 @@ uint32_t interrupt_disable(uint32_t irq, void *arg) | ||
| if (cascade) | ||
| return irq_disable_child(cascade, irq, arg); | ||
| #if defined(__ZEPHYR__) && defined(CONFIG_IMX) | ||
| /* undefine the macro so that interrupt_disable() | ||
| * is resolved to the one from wrapper.c | ||
| */ | ||
| #undef interrupt_disable | ||
| return interrupt_disable(irq, arg); | ||
| #else | ||
| return arch_interrupt_disable_mask(1 << irq); | ||
| #endif | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -34,7 +34,7 @@ struct ll_task_pdata { | ||
| uint16_t skip_cnt; /**< how many times the task was skipped for execution */ | ||
| }; | ||
| #ifndef __ZEPHYR__ | ||
| #if !defined(__ZEPHYR__) || defined(CONFIG_IMX) | ||
| ||
| int scheduler_init_ll(struct ll_schedule_domain *domain); | ||
| int schedule_task_init_ll(struct task *task, | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -113,6 +113,11 @@ if (CONFIG_SOC_SERIES_INTEL_ADSP_BAYTRAIL) | ||
| ${SOF_SRC_PATH}/schedule/dma_multi_chan_domain.c | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/ll_schedule.c | ||
| ) | ||
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you respin this PR, please merge this with the previous commit to avoid breaking bisection, even though these platforms don't actually work with Zephyr... ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done | ||
| set(PLATFORM "baytrail") | ||
| endif() | ||
| @@ -123,6 +128,11 @@ if (CONFIG_SOC_SERIES_INTEL_ADSP_BROADWELL) | ||
| ${SOF_DRIVERS_PATH}/intel/haswell/ssp.c | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/ll_schedule.c | ||
| ) | ||
| set(PLATFORM "haswell") | ||
| endif() | ||
| @@ -177,6 +187,11 @@ if (CONFIG_SOC_SERIES_INTEL_CAVS_V15) | ||
| ${SOF_PLATFORM_PATH}/apollolake/lib/clk.c | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/zephyr_ll.c | ||
| ) | ||
| set_source_files_properties(${SOF_PLATFORM_PATH}/apollolake/lib/power_down.S PROPERTIES COMPILE_FLAGS -DASSEMBLY) | ||
| set(PLATFORM "apollolake") | ||
| @@ -239,6 +254,11 @@ if (CONFIG_SOC_SERIES_INTEL_CAVS_V18) | ||
| #${SOF_PLATFORM_PATH}/intel/cavs/lps_pic_restore_vector.S | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/zephyr_ll.c | ||
| ) | ||
| zephyr_library_sources_ifdef(CONFIG_CAVS_LPS | ||
| ${SOF_PLATFORM_PATH}/intel/cavs/lps_wait.c | ||
| ) | ||
| @@ -302,6 +322,11 @@ if (CONFIG_SOC_SERIES_INTEL_CAVS_V20) | ||
| #${SOF_PLATFORM_PATH}/intel/cavs/lps_pic_restore_vector.S | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/zephyr_ll.c | ||
| ) | ||
| zephyr_library_sources_ifdef(CONFIG_CAVS_LPS | ||
| ${SOF_PLATFORM_PATH}/intel/cavs/lps_wait.c | ||
| ) | ||
| @@ -368,6 +393,11 @@ if (CONFIG_SOC_SERIES_INTEL_CAVS_V25) | ||
| #${SOF_PLATFORM_PATH}/intel/cavs/lps_pic_restore_vector.S | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/zephyr_ll.c | ||
| ) | ||
| zephyr_library_sources_ifdef(CONFIG_CAVS_LPS | ||
| ${SOF_PLATFORM_PATH}/intel/cavs/lps_wait.c | ||
| ) | ||
| @@ -389,6 +419,7 @@ if (CONFIG_SOC_SERIES_NXP_IMX8) | ||
| ${SOF_DRIVERS_PATH}/imx/sai.c | ||
| ${SOF_DRIVERS_PATH}/imx/ipc.c | ||
| ${SOF_DRIVERS_PATH}/imx/esai.c | ||
| ${SOF_DRIVERS_PATH}/imx/interrupt-irqsteer.c | ||
| ) | ||
| # Platform sources | ||
| @@ -400,6 +431,12 @@ if (CONFIG_SOC_SERIES_NXP_IMX8) | ||
| ${SOF_PLATFORM_PATH}/imx8/lib/memory.c | ||
| ) | ||
| # SOF core infrastructure - runs on top of Zephyr | ||
| zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/ll_schedule.c | ||
iuliana-prodan marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| ${SOF_SRC_PATH}/drivers/interrupt.c | ||
| ) | ||
| set(PLATFORM "imx8") | ||
| endif() | ||
| @@ -479,7 +516,6 @@ zephyr_library_sources( | ||
| ${SOF_SRC_PATH}/schedule/schedule.c | ||
| ${SOF_SRC_PATH}/schedule/dma_single_chan_domain.c | ||
| ${SOF_SRC_PATH}/schedule/dma_multi_chan_domain.c | ||
| ${SOF_SRC_PATH}/schedule/zephyr_ll.c | ||
| ${SOF_SRC_PATH}/schedule/zephyr.c | ||
| # Bridge wrapper between SOF and Zephyr APIs - Will shrink over time. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -255,28 +255,6 @@ void heap_trace_all(int force) | ||
| const char irq_name_level2[] = "level2"; | ||
| const char irq_name_level5[] = "level5"; | ||
| /* | ||
| * CAVS IRQs are multilevel whereas BYT and BDW are DSP level only. | ||
| * | ||
| * For i.MX we use the IRQ_STEER | ||
| */ | ||
| int interrupt_get_irq(unsigned int irq, const char *cascade) | ||
| { | ||
| #if CONFIG_SOC_SERIES_INTEL_ADSP_BAYTRAIL ||\ | ||
| CONFIG_SOC_SERIES_INTEL_ADSP_BROADWELL || \ | ||
| CONFIG_IMX || \ | ||
| CONFIG_LIBRARY | ||
| return irq; | ||
| #else | ||
| if (cascade == irq_name_level2) | ||
| return SOC_AGGREGATE_IRQ(irq, IRQ_NUM_EXT_LEVEL2); | ||
| if (cascade == irq_name_level5) | ||
| return SOC_AGGREGATE_IRQ(irq, IRQ_NUM_EXT_LEVEL5); | ||
| return SOC_AGGREGATE_IRQ(0, irq); | ||
| #endif | ||
| } | ||
| int interrupt_register(uint32_t irq, void(*handler)(void *arg), void *arg) | ||
| { | ||
| #ifdef CONFIG_DYNAMIC_INTERRUPTS | ||
| @@ -319,6 +297,29 @@ uint32_t interrupt_disable(uint32_t irq, void *arg) | ||
| } | ||
| #endif | ||
| /* | ||
| * i.MX uses the IRQ_STEER | ||
| */ | ||
| #if !CONFIG_IMX | ||
| /* | ||
| * CAVS IRQs are multilevel whereas BYT and BDW are DSP level only. | ||
| */ | ||
| int interrupt_get_irq(unsigned int irq, const char *cascade) | ||
| { | ||
| #if CONFIG_SOC_SERIES_INTEL_ADSP_BAYTRAIL ||\ | ||
| CONFIG_SOC_SERIES_INTEL_ADSP_BROADWELL || \ | ||
| CONFIG_LIBRARY | ||
| return irq; | ||
| #else | ||
| if (cascade == irq_name_level2) | ||
| return SOC_AGGREGATE_IRQ(irq, IRQ_NUM_EXT_LEVEL2); | ||
| if (cascade == irq_name_level5) | ||
| return SOC_AGGREGATE_IRQ(irq, IRQ_NUM_EXT_LEVEL5); | ||
| return SOC_AGGREGATE_IRQ(0, irq); | ||
| #endif | ||
| } | ||
| void interrupt_mask(uint32_t irq, unsigned int cpu) | ||
| { | ||
| /* TODO: how do we mask on other cores with Zephyr APIs */ | ||
| @@ -343,6 +344,7 @@ void platform_interrupt_clear(uint32_t irq, uint32_t mask) | ||
| { | ||
| /* handled by zephyr - needed for linkage */ | ||
| } | ||
| #endif | ||
| /* | ||
| * Timers. | ||
| @@ -609,8 +611,14 @@ int task_main_start(struct sof *sof) | ||
| /* init pipeline position offsets */ | ||
| pipeline_posn_init(sof); | ||
| #if defined(CONFIG_IMX) | ||
| #define SOF_IPC_QUEUED_DOMAIN SOF_SCHEDULE_LL_DMA | ||
| #else | ||
iuliana-prodan marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| #define SOF_IPC_QUEUED_DOMAIN SOF_SCHEDULE_LL_TIMER | ||
| #endif | ||
| /* Temporary fix for issue #4356 */ | ||
| (void)notifier_register(NULL, scheduler_get_data(SOF_SCHEDULE_LL_TIMER), | ||
| (void)notifier_register(NULL, scheduler_get_data(SOF_IPC_QUEUED_DOMAIN), | ||
| NOTIFIER_ID_LL_POST_RUN, | ||
| ipc_send_queued_callback, 0); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have to re-spin this PR to address @marc-hb 's comment, could you also add to this comment, that because of this currently i.MX with Zephyr has to use both wrapper.c and this file which causes name collisions. That's why you need these defines. And below where you
#undeffor the first time, please add a comment saying, that that will now call the version from wrapper.c@lgirdwood in fact this seems like a good candidate for an early native Zephyr API conversion: if we could switch over to native
z_soc_irq_*()everywhere in the code with wrappers for XTOS builds, we wouldn't need this?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. @lyakh@iuliana-prodan what's the effort in switching over the APIs for Intel and NXP code ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marc-hb the irq wrapping as discussed on call