Repository navigation
Conversation
|
Here's the dmesg log from the point when suspend occurs until after the firmware boots up. |
|
From kernel log, rmbox should be not work ? so no rmbox message? And I think each internal buffer pointer or component status should be kept ?Or OS would send hw_param and start again? |
|
What happens to all the components created when the topology is loaded before suspend? Should the topology be reloaded after resume? |
|
I am not sure: some memory in DSP is still valid, so it can be used to keep some status |
|
@ranj063 : I don't think the topology should be parsed again on resume, but certainly anything that results in an IPC should be invoked on resume, e.g. SSP settings and pipeline commands (likely why the hw_params fail). I am afraid today we combined token parsing and IPC, maybe not such a good idea in hindsight. |
|
@ranj063 we probably dont want to pasre the topology again, but sof/topology.c does track a lot of the topology structures locally when probing. i.e. we have a list of widgets, controls etc. We should store a pointer to the topology raw structure for each topology object and on resume we iterate through all the topology object lists and send IPCs. |
|
@plbossart @lgirdwood Thanks! Let me re-send the ipc's to restore the pipeline from the topology objects stored in the driver. |
|
@plbossart @lgirdwood , I have updated the commits in this pull request to restore the pipeline at resume. |
|
@ranj063 ok, half way there now. Have a look at the legacy baytrail driver (sound/soc/intel/baytral/*) as it stores PCM playback state prior to S3 and restores at S0. You probably need to duplicate this flow. |
There was a problem hiding this comment.
What about if we have 2 or more pipelines ? If this restores all pipelines then maybe rename func.
There was a problem hiding this comment.
Just wondering if we need all these case statements given all the IPC data uses a standard header (which includes cmd and size). i.e. we cas the private data to the header type to get size and cmd.
There was a problem hiding this comment.
@lgirdwood I started it that way but I kept running into errors with it. The only way I can send the ipc without errors is by having all these case statements.
There was a problem hiding this comment.
ok, interesting, what errors ? The only thing the case statements do is cast types
There was a problem hiding this comment.
@lgirdwood. I've fixed it now. The error I was seeing was because of not casting the comp objects to (void *) while storing them.
There was a problem hiding this comment.
Best to try and send this today as it allows DSP to enter D3 ready state. Any context can be saved later.
There was a problem hiding this comment.
I'd expect most of this function to be in pm.c as generic code. The HW specific part hda_dsp_core_reset_power_down() can be an HW abstracted operation (add ops to the operations callback structure). e.g. we could have snd_sof_dsp_suspend(sdev), snd_sof_dsp_resume(sdev)
There was a problem hiding this comment.
Agree with Liam, this feels too APL-specific.
There was a problem hiding this comment.
@plbossart @lgirdwood I have updated this to use the chip cores_mask to make it generic.
|
@lgirdwood I've just pushed the v3 changes. Now I can resume audio playback normally after suspend/resume. There's an occasional xrun that happens at resume but its been hard to reproduce. |
lgirdwood
left a comment
There was a problem hiding this comment.
Mostly minor things, glad its working now :)
There was a problem hiding this comment.
Btw, we need to be able to handle different core masks, e.g. APL has 2, CNL has 4.
There was a problem hiding this comment.
@lgirdwood sure. I have tested this to work only for APL as yet. I will make the changes for CNL next.
There was a problem hiding this comment.
ok, interesting, what errors ? The only thing the case statements do is cast types
There was a problem hiding this comment.
I'd make the stream suspend a separate function
There was a problem hiding this comment.
Where do we send the IPC start message if we set cmd here ?
There was a problem hiding this comment.
@lgirdwood It is sent right outside the switch/case block where we set the cmd.
plbossart
left a comment
There was a problem hiding this comment.
Looks good overall, still some style issues and my usual quixotic chase of memory leaks. One functional part also to align times with the firmware so that on resume the trace logs aren't completely misleading.
There was a problem hiding this comment.
For the volume case, don't you need to free swidget->private?
There was a problem hiding this comment.
need to free sroute first? this doesn't look consistent error management, or do you assume that all frees are done in an sof_route_unload()?
There was a problem hiding this comment.
you need a more consistent memory allocation/free. Here you free on one error, but not for all the other cases in this function below (look for all the return -EINVAL cases). You should have a set of gotos and deal with errors in a more organized way, or you deal with all the frees in another cleanup routine called on failure.
There was a problem hiding this comment.
oh yes. let me address this. seems like I've missed the route_load case to fix the memory allocation/free.
There was a problem hiding this comment.
well, duh. Can you please update this one, this will create issues with module load/unload and break CI.
There was a problem hiding this comment.
@plbossart sure, I am working on it. It wasnt very straightforward which route is being unloaded from the arguments. I need to study this a bit more to implement it correctly.
There was a problem hiding this comment.
@plbossart @lgirdwood it doesnt look like route_unload ever gets called.
I see a comment in soc-topology.c in the remove_widget() function that suggests that routes must
be removed before the widget itself is removed. But I cant find any references to route_unload.
Also, the arguments to the route_unload() method seem ambiguous. There's no dobj member in snd_soc_dapm_route structure. So I'm not sure how to get a handle to it in order to be able to remove it. Can you please help?
There was a problem hiding this comment.
You will need to deep dive this more as I'm short of time and may also need to modify the API if needed to pass in the extra info.
There was a problem hiding this comment.
Looks like we still have a dependency on a core cleanup?
There was a problem hiding this comment.
need explicit /* fallthrough */ to make tools happy that this is not a programming error
There was a problem hiding this comment.
Thanks for the reminder. I'll add this where appropriate.
There was a problem hiding this comment.
ret is not tested in most cases?
There was a problem hiding this comment.
@plbossart ret is tested right outside the switch/case block to make sure none of the ipc's failed.
There was a problem hiding this comment.
shouldn't there be some IPC sent on suspend, so that e.g. if there is any sort of context saving at the firmware level they'd know about it?
There was a problem hiding this comment.
@plbossart I do send the CTX_SAVE ipc during suspend in the suspend callback but not here as it is not a stream ipc message.
There was a problem hiding this comment.
BTW on resume we'd need to pass the new wall clock time to the firmware so that any trace logs are timestamped with the right values.
There was a problem hiding this comment.
@plbossart good point. Let me add it if we're not doing that already.
|
@plbossart @lgirdwood I've made some more changes to the flow now. |
lgirdwood
left a comment
There was a problem hiding this comment.
Sorry could not see the opens you mentioned ?
There was a problem hiding this comment.
Would also be good to see the widget type failing here swidget->id, we would then have the type and id.
|
@lgirdwood the two opens left are:
|
|
@ranj063 do you want us to review/test now or will the two opens come shortly enough that we want to wait for the update. |
|
@plbossart I should be done with the 2 opens by today and I think it will be better to test after those. But I've made some change regarding which device we register the PM callbacks for. I could use some feedback to make sure I've done the right thing. |
|
@ranj063 can you describe the device change so that the rest of us don't have to reverse-engineer the deltas between patches? |
|
@plbossart this is the commit id for the device change in this patchset: With the callbacks set for the pci device, they never get called as the runtime_pm_enable() is called for the platform device and not the pci device. So setting the callbacks for the platform device fixes the issue. |
|
@ranj063 for the kcontrol restore, iirc baytrail/haswell drivers did this by caching the values in the host. |
|
@lgirdwood, sure. I think I have an idea of how to do this. I will update the PR after I fix it. |
|
@plbossart @lgirdwood I've addressed all opens now. Could I request you to please review the latest version. |
ACPICA commit 807665510f1ea71bbdc063c27782a1da56e8e10a Before this change we see the following UBSAN stack trace in Fuchsia: #0 0x00002234800696e6 in acpi_tb_get_root_table_entry(u8*, u32) ../../third_party/acpica/source/components/tables/tbutils.c:231 <platform-bus-x86.so>+0x9106e6 thesofproject#1.2 0x0000233d72c8777f in ubsan_get_stack_trace() compiler-rt/lib/ubsan/ubsan_diag.cpp:41 <libclang_rt.asan.so>+0x3d77f thesofproject#1.1 0x0000233d72c8777f in maybe_print_stack_trace() compiler-rt/lib/ubsan/ubsan_diag.cpp:51 <libclang_rt.asan.so>+0x3d77f thesofproject#1 0x0000233d72c8777f in ~scoped_report() compiler-rt/lib/ubsan/ubsan_diag.cpp:387 <libclang_rt.asan.so>+0x3d77f thesofproject#2 0x0000233d72c88385 in handletype_mismatch_impl() compiler-rt/lib/ubsan/ubsan_handlers.cpp:137 <libclang_rt.asan.so>+0x3e385 thesofproject#3 0x0000233d72c87ead in compiler-rt/lib/ubsan/ubsan_handlers.cpp:142 <libclang_rt.asan.so>+0x3dead thesofproject#4 0x00002234800696e6 in acpi_tb_get_root_table_entry(u8*, u32) ../../third_party/acpica/source/components/tables/tbutils.c:231 <platform-bus-x86.so>+0x9106e6 thesofproject#5 0x00002234800691dd in acpi_tb_parse_root_table(acpi_physical_address) ../../third_party/acpica/source/components/tables/tbutils.c:385 <platform-bus-x86.so>+0x9101dd thesofproject#6 0x0000223480070b06 in acpi_initialize_tables(struct acpi_table_desc*, u32, u8) ../../third_party/acpica/source/components/tables/tbxface.c:160 <platform-bus-x86.so>+0x917b06 thesofproject#7 0x000022347fb803b4 in acpi::acpi_impl::initialize_acpi(acpi::acpi_impl*) ../../src/devices/board/lib/acpi/acpi-impl.cc:200 <platform-bus-x86.so>+0x4273b4 thesofproject#8 0x000022347fa30d14 in x86::X86::early_acpi_init(x86::X86*) ../../src/devices/board/drivers/x86/init.cc:34 <platform-bus-x86.so>+0x2d7d14 thesofproject#9 0x000022347fa310cf in x86::X86::early_init(x86::X86*) ../../src/devices/board/drivers/x86/init.cc:43 <platform-bus-x86.so>+0x2d80cf thesofproject#10 0x000022347fa79410 in x86::X86::Bind(x86::X86*) ../../src/devices/board/drivers/x86/x86.cc:144 <platform-bus-x86.so>+0x320410 thesofproject#11 0x000022347fa78ec0 in x86::X86::create_and_bind(void*, zx_device_t*) ../../src/devices/board/drivers/x86/x86.cc:123 <platform-bus-x86.so>+0x31fec0 thesofproject#12 0x000020dc8908502f in λ(const zx_driver::bind_op::(anon class)*) ../../src/devices/bin/driver_host/zx_driver.cc:36 <<application>>+0x41502f thesofproject#13 0x000020dc89084e03 in fit::internal::target<(lambda at../../src/devices/bin/driver_host/zx_driver.cc:34:61), false, false, void>::invoke(void*) ../../sdk/lib/fit/include/lib/fit/internal/function.h:181 <<application>>+0x414e03 thesofproject#14 0x000020dc8935a930 in fit::internal::function_base<16UL, false, void()>::invoke(const fit::internal::function_base<16UL, false, void ()>*) ../../sdk/lib/fit/include/lib/fit/internal/function.h:505 <<application>>+0x6ea930 thesofproject#15 0x000020dc893e2f8a in fit::function_impl<16UL, false, void()>::operator()(const fit::function_impl<16UL, false, void ()>*) ../../sdk/lib/fit/include/lib/fit/function.h:300 <<application>>+0x772f8a thesofproject#16 0x000020dc8948dec5 in async::internal::retained_task::Handler(async_dispatcher_t*, async_task_t*, zx_status_t) ../../zircon/system/ulib/async/task.cc:25 <<application>>+0x81dec5 thesofproject#17 0x000023ab5abcf91e in λ(const driver_runtime::Dispatcher::post_task::(anon class)*, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, zx_status_t) ../../src/devices/bin/driver_runtime/dispatcher.cc:715 <libdriver_runtime.so>+0xed91e thesofproject#18 0x000023ab5abcf621 in fit::internal::target<(lambda at../../src/devices/bin/driver_runtime/dispatcher.cc:714:7), true, false, void, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request>>, int>::invoke(void*, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, int) ../../sdk/lib/fit/include/lib/fit/internal/function.h:128 <libdriver_runtime.so>+0xed621 thesofproject#19 0x000023ab5abaa482 in fit::internal::function_base<24UL, true, void(std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request>>, int)>::invoke(const fit::internal::function_base<24UL, true, void (std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, int)>*, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, int) ../../sdk/lib/fit/include/lib/fit/internal/function.h:505 <libdriver_runtime.so>+0xc8482 thesofproject#20 0x000023ab5abaa0f8 in fit::callback_impl<24UL, true, void(std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request>>, int)>::operator()(fit::callback_impl<24UL, true, void (std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, int)>*, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, int) ../../sdk/lib/fit/include/lib/fit/function.h:451 <libdriver_runtime.so>+0xc80f8 thesofproject#21 0x000023ab5ab81c76 in driver_runtime::callback_request::Call(driver_runtime::callback_request*, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >, zx_status_t) ../../src/devices/bin/driver_runtime/callback_request.h:67 <libdriver_runtime.so>+0x9fc76 thesofproject#22 0x000023ab5ab8e7ef in driver_runtime::Dispatcher::dispatch_callback(driver_runtime::Dispatcher*, std::__2::unique_ptr<driver_runtime::callback_request, std::__2::default_delete<driver_runtime::callback_request> >) ../../src/devices/bin/driver_runtime/dispatcher.cc:1093 <libdriver_runtime.so>+0xac7ef thesofproject#23 0x000023ab5ab91d67 in driver_runtime::Dispatcher::dispatch_callbacks(driver_runtime::Dispatcher*, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>) ../../src/devices/bin/driver_runtime/dispatcher.cc:1169 <libdriver_runtime.so>+0xafd67 thesofproject#24 0x000023ab5abbe9a2 in λ(const driver_runtime::Dispatcher::create_with_adder::(anon class)*, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>) ../../src/devices/bin/driver_runtime/dispatcher.cc:338 <libdriver_runtime.so>+0xdc9a2 thesofproject#25 0x000023ab5abbe6d2 in fit::internal::target<(lambda at../../src/devices/bin/driver_runtime/dispatcher.cc:337:7), true, false, void, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter>>, fbl::ref_ptr<driver_runtime::Dispatcher>>::invoke(void*, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>) ../../sdk/lib/fit/include/lib/fit/internal/function.h:128 <libdriver_runtime.so>+0xdc6d2 thesofproject#26 0x000023ab5abac1e5 in fit::internal::function_base<8UL, true, void(std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter>>, fbl::ref_ptr<driver_runtime::Dispatcher>)>::invoke(const fit::internal::function_base<8UL, true, void (std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>)>*, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>) ../../sdk/lib/fit/include/lib/fit/internal/function.h:505 <libdriver_runtime.so>+0xca1e5 thesofproject#27 0x000023ab5ababe32 in fit::function_impl<8UL, true, void(std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter>>, fbl::ref_ptr<driver_runtime::Dispatcher>)>::operator()(const fit::function_impl<8UL, true, void (std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>)>*, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>) ../../sdk/lib/fit/include/lib/fit/function.h:300 <libdriver_runtime.so>+0xc9e32 thesofproject#28 0x000023ab5ab95444 in driver_runtime::Dispatcher::event_waiter::invoke_callback(driver_runtime::Dispatcher::event_waiter*, std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, fbl::ref_ptr<driver_runtime::Dispatcher>) ../../src/devices/bin/driver_runtime/dispatcher.h:299 <libdriver_runtime.so>+0xb3444 thesofproject#29 0x000023ab5ab94feb in driver_runtime::Dispatcher::event_waiter::handle_event(std::__2::unique_ptr<driver_runtime::Dispatcher::event_waiter, std::__2::default_delete<driver_runtime::Dispatcher::event_waiter> >, async_dispatcher_t*, async::wait_base*, zx_status_t, zx_packet_signal_t const*) ../../src/devices/bin/driver_runtime/dispatcher.cc:1259 <libdriver_runtime.so>+0xb2feb thesofproject#30 0x000023ab5abbef74 in async_loop_owned_event_handler<driver_runtime::Dispatcher::event_waiter>::handle_event(async_loop_owned_event_handler<driver_runtime::Dispatcher::event_waiter>*, async_dispatcher_t*, async::wait_base*, zx_status_t, zx_packet_signal_t const*) ../../src/devices/bin/driver_runtime/async_loop_owned_event_handler.h:59 <libdriver_runtime.so>+0xdcf74 thesofproject#31 0x000023ab5abbf1cb in async::wait_method<async_loop_owned_event_handler<driver_runtime::Dispatcher::event_waiter>, &async_loop_owned_event_handler<driver_runtime::Dispatcher::event_waiter>::handle_event>::call_handler(async_dispatcher_t*, async_wait_t*, zx_status_t, zx_packet_signal_t const*) ../../zircon/system/ulib/async/include/lib/async/cpp/wait.h:201 <libdriver_runtime.so>+0xdd1cb thesofproject#32 0x000023ab5ac323a9 in async_loop_dispatch_wait(async_loop_t*, async_wait_t*, zx_status_t, zx_packet_signal_t const*) ../../zircon/system/ulib/async-loop/loop.c:381 <libdriver_runtime.so>+0x1503a9 thesofproject#33 0x000023ab5ac2ba82 in async_loop_run_once(async_loop_t*, zx_time_t) ../../zircon/system/ulib/async-loop/loop.c:330 <libdriver_runtime.so>+0x149a82 thesofproject#34 0x000023ab5ac2b102 in async_loop_run(async_loop_t*, zx_time_t, _Bool) ../../zircon/system/ulib/async-loop/loop.c:288 <libdriver_runtime.so>+0x149102 thesofproject#35 0x000023ab5ac2ceb7 in async_loop_run_thread(void*) ../../zircon/system/ulib/async-loop/loop.c:840 <libdriver_runtime.so>+0x14aeb7 thesofproject#36 0x000040b3be411f1c in start_c11(void*) ../../zircon/third_party/ulib/musl/pthread/pthread_create.c:55 <libc.so>+0xd7f1c thesofproject#37 0x000040b3be53ce8d in thread_trampoline(uintptr_t, uintptr_t) ../../zircon/system/ulib/runtime/thread.cc:100 <libc.so>+0x202e8d Link: open-acpica/acpica@80766551 Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This patchset aims to implement the preliminary flow for suspend/resume for APL.
V2: Now the pipeline status is restored at resume by sending the ipc's to create all the components and set up the pipeline. With this change, the DSP is power off at suspend and when it resumes from suspend, audio playback works normally.
But when suspend is invoked while audio playback is in progress, playback does not resume and aplay quits with the error "pcm_write:2011: write error: Input/output error".
V3: changes made to reflect previous comments
Audio playback resumes normally after suspend/resume.
V4: Added support for runtime PM and made changes based on previous feedback.
Now, both runtime PM and suspend/resume work well.
2 tasks still left to do: