-
Notifications
You must be signed in to change notification settings - Fork 349
lps: restore secondary cores on wake up #4839
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
Changes from all commits
c7a23e2
0452b85
b507987
28c23a4
50b8d5a
cd59a28
7d559a3
5314d67
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -160,25 +160,44 @@ void cpu_alloc_core_context(int core) | |
| dcache_writeback_region(sof_get(), sizeof(*sof_get())); | ||
| } | ||
|
|
||
| void cpu_power_down_core(void) | ||
| void cpu_power_down_core(uint32_t flags) | ||
| { | ||
| arch_interrupt_global_disable(); | ||
|
|
||
| idc_free(); | ||
| /* Power down with memory on is performed by secondary cores during | ||
| * d0 -> d0ix before they are disabled by primary core. | ||
| */ | ||
| if (flags & CPU_POWER_DOWN_MEMORY_ON) { | ||
| /* disable idc interrupts */ | ||
| idc_free(IDC_FREE_IRQ_ONLY); | ||
|
|
||
| /* disable scheduler interrupts */ | ||
| schedule_free(SOF_SCHEDULER_FREE_IRQ_ONLY); | ||
|
|
||
| /* data writeback/invalidate */ | ||
| dcache_writeback_invalidate_all(); | ||
|
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. add a comment, that after this point we aren't "polluting" any more cache lines?..
Collaborator
Author
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. I do not understand what do you mean by "polluting" here?
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. making clean cache lines dirty (is there an official term for this?). I.e. writing to cached memory, without forcing cache write-back. |
||
|
|
||
| schedule_free(); | ||
| /* after writeback/invalidate secondary core is prepared for | ||
| * powered off - prepare_d0ix_core_mask flag can be disabled | ||
| */ | ||
| platform_pm_runtime_prepare_d0ix_dis(cpu_get_id()); | ||
| } else { | ||
| idc_free(0); | ||
|
|
||
| free_system_notify(); | ||
| schedule_free(0); | ||
|
|
||
| /* free entire sys heap, an instance dedicated for this core */ | ||
| free_heap(SOF_MEM_ZONE_SYS); | ||
| free_system_notify(); | ||
|
|
||
| dcache_writeback_invalidate_all(); | ||
| /* free entire sys heap, an instance dedicated for this core */ | ||
| free_heap(SOF_MEM_ZONE_SYS); | ||
|
|
||
| /* Turn off stack memory for core */ | ||
| pm_runtime_put(CORE_MEMORY_POW, cpu_get_id()); | ||
| dcache_writeback_invalidate_all(); | ||
|
|
||
| pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_TPLG | cpu_get_id()); | ||
| /* Turn off stack memory for core */ | ||
| pm_runtime_put(CORE_MEMORY_POW, cpu_get_id()); | ||
|
|
||
| pm_runtime_put(PM_RUNTIME_DSP, PWRD_BY_TPLG | cpu_get_id()); | ||
| } | ||
|
|
||
| trace_point(0); | ||
|
|
||
|
|
@@ -189,3 +208,50 @@ void cpu_power_down_core(void) | |
| while (1) | ||
| arch_wait_for_interrupt(0); | ||
| } | ||
|
|
||
| int arch_cpu_restore_secondary_cores(void) | ||
bkokoszx marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| struct idc_msg power_up = { IDC_MSG_POWER_UP, IDC_MSG_POWER_UP_EXT }; | ||
| int ret, id; | ||
|
|
||
| for (id = 0; id < CONFIG_CORE_COUNT; id++) { | ||
| if (arch_cpu_is_core_enabled(id) && id != PLATFORM_PRIMARY_CORE_ID) { | ||
| power_up.core = id; | ||
|
|
||
| /* Power up secondary core */ | ||
| pm_runtime_get(PM_RUNTIME_DSP, id); | ||
|
|
||
| /* enable IDC interrupt for the secondary core */ | ||
| idc_enable_interrupts(id, cpu_get_id()); | ||
|
|
||
| /* send IDC power up message */ | ||
| ret = idc_send_msg(&power_up, IDC_POWER_UP); | ||
| if (ret < 0) | ||
| return ret; | ||
| } | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| int arch_cpu_secondary_cores_prepare_d0ix(void) | ||
| { | ||
| struct idc_msg prepare_msg = { IDC_MSG_PREPARE_D0ix, | ||
| IDC_MSG_PREPARE_D0ix_EXT }; | ||
| int ret, id; | ||
|
|
||
| for (id = 0; id < CONFIG_CORE_COUNT; id++) { | ||
| if (arch_cpu_is_core_enabled(id) && id != PLATFORM_PRIMARY_CORE_ID) { | ||
| prepare_msg.core = id; | ||
|
|
||
| /* send IDC prepare message to all enabled secondary | ||
| * cores. | ||
| */ | ||
| ret = idc_send_msg(&prepare_msg, IDC_BLOCKING); | ||
| if (ret < 0) | ||
| return ret; | ||
| } | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.