Skip to content

Commit ba41906

Browse files
committed
ASoC: SOF: Add one more state for DMA trace
Currently DMA trace has only 2 states: enabled or disabled. However DMA trace may have more states. For example, enabled but not started. This patch refines the dma trace to provide a mechanism to store more states than enabled/disabled and adds SOF_DTRACE_STOPPED state. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Libin Yang <libin.yang@intel.com>
1 parent dc91bdf commit ba41906

File tree

3 files changed

+57
-21
lines changed

3 files changed

+57
-21
lines changed

sound/soc/sof/pm.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ static int sof_resume(struct device *dev, bool runtime_resume)
149149
return ret;
150150
}
151151

152-
/* resume DMA trace, only need send ipc */
153-
ret = snd_sof_init_trace_ipc(sdev);
152+
/* resume DMA trace */
153+
ret = snd_sof_trace_resume(sdev);
154154
if (ret < 0) {
155155
/* non fatal */
156156
dev_warn(sdev->dev,
@@ -220,8 +220,8 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
220220

221221
sof_tear_down_pipelines(sdev, false);
222222

223-
/* release trace */
224-
snd_sof_release_trace(sdev);
223+
/* suspend DMA trace */
224+
snd_sof_trace_suspend(sdev, SOF_DSP_PM_D3);
225225

226226
/* Notify clients not managed by pm framework about core suspend */
227227
sof_suspend_clients(sdev, pm_state);

sound/soc/sof/sof-priv.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,12 @@ struct snd_sof_ipc {
374374
struct snd_sof_ipc_msg msg;
375375
};
376376

377+
enum sof_dtrace_state {
378+
SOF_DTRACE_DISABLED,
379+
SOF_DTRACE_STOPPED,
380+
SOF_DTRACE_ENABLED,
381+
};
382+
377383
/*
378384
* SOF Device Level.
379385
*/
@@ -461,9 +467,9 @@ struct snd_sof_dev {
461467
wait_queue_head_t trace_sleep;
462468
u32 host_offset;
463469
bool dtrace_is_supported; /* set with Kconfig or module parameter */
464-
bool dtrace_is_enabled;
465470
bool dtrace_error;
466471
bool dtrace_draining;
472+
enum sof_dtrace_state dtrace_state;
467473

468474
bool msi_enabled;
469475

@@ -568,7 +574,6 @@ static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_i
568574
* Trace/debug
569575
*/
570576
int snd_sof_init_trace(struct snd_sof_dev *sdev);
571-
void snd_sof_release_trace(struct snd_sof_dev *sdev);
572577
void snd_sof_free_trace(struct snd_sof_dev *sdev);
573578
int snd_sof_dbg_init(struct snd_sof_dev *sdev);
574579
void snd_sof_free_debug(struct snd_sof_dev *sdev);
@@ -582,7 +587,8 @@ void sof_print_oops_and_stack(struct snd_sof_dev *sdev, const char *level,
582587
u32 panic_code, u32 tracep_code, void *oops,
583588
struct sof_ipc_panic_info *panic_info,
584589
void *stack, size_t stack_words);
585-
int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev);
590+
int snd_sof_trace_suspend(struct snd_sof_dev *sdev, int pm_state);
591+
int snd_sof_trace_resume(struct snd_sof_dev *sdev);
586592
void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev);
587593
int snd_sof_dbg_memory_info_init(struct snd_sof_dev *sdev);
588594
int snd_sof_debugfs_add_region_item_iomem(struct snd_sof_dev *sdev,

sound/soc/sof/trace.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/debugfs.h>
1212
#include <linux/sched/signal.h>
1313
#include "sof-priv.h"
14+
#include "sof-audio.h"
1415
#include "ops.h"
1516
#include "sof-utils.h"
1617

@@ -263,7 +264,7 @@ static size_t sof_wait_trace_avail(struct snd_sof_dev *sdev,
263264
if (ret)
264265
return ret;
265266

266-
if (!sdev->dtrace_is_enabled && sdev->dtrace_draining) {
267+
if (sdev->dtrace_state != SOF_DTRACE_ENABLED && sdev->dtrace_draining) {
267268
/*
268269
* tracing has ended and all traces have been
269270
* read by client, return EOF
@@ -337,7 +338,7 @@ static int sof_dfsentry_trace_release(struct inode *inode, struct file *file)
337338
struct snd_sof_dev *sdev = dfse->sdev;
338339

339340
/* avoid duplicate traces at next open */
340-
if (!sdev->dtrace_is_enabled)
341+
if (sdev->dtrace_state != SOF_DTRACE_ENABLED)
341342
sdev->host_offset = 0;
342343

343344
return 0;
@@ -377,7 +378,7 @@ static int trace_debugfs_create(struct snd_sof_dev *sdev)
377378
return 0;
378379
}
379380

380-
int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
381+
static int snd_sof_enable_trace(struct snd_sof_dev *sdev)
381382
{
382383
struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
383384
struct sof_ipc_fw_version *v = &ready->version;
@@ -388,9 +389,12 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
388389
if (!sdev->dtrace_is_supported)
389390
return 0;
390391

391-
if (sdev->dtrace_is_enabled || !sdev->dma_trace_pages)
392+
if (sdev->dtrace_state == SOF_DTRACE_ENABLED || !sdev->dma_trace_pages)
392393
return -EINVAL;
393394

395+
if (sdev->dtrace_state == SOF_DTRACE_STOPPED)
396+
goto start;
397+
394398
/* set IPC parameters */
395399
params.hdr.cmd = SOF_IPC_GLB_TRACE_MSG;
396400
/* PARAMS_EXT is only supported from ABI 3.7.0 onwards */
@@ -428,14 +432,15 @@ int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev)
428432
goto trace_release;
429433
}
430434

435+
start:
431436
ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_START);
432437
if (ret < 0) {
433438
dev_err(sdev->dev,
434439
"error: snd_sof_dma_trace_trigger: start: %d\n", ret);
435440
goto trace_release;
436441
}
437442

438-
sdev->dtrace_is_enabled = true;
443+
sdev->dtrace_state = SOF_DTRACE_ENABLED;
439444

440445
return 0;
441446

@@ -452,7 +457,7 @@ int snd_sof_init_trace(struct snd_sof_dev *sdev)
452457
return 0;
453458

454459
/* set false before start initialization */
455-
sdev->dtrace_is_enabled = false;
460+
sdev->dtrace_state = SOF_DTRACE_DISABLED;
456461

457462
/* allocate trace page table buffer */
458463
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
@@ -490,7 +495,7 @@ int snd_sof_init_trace(struct snd_sof_dev *sdev)
490495

491496
init_waitqueue_head(&sdev->trace_sleep);
492497

493-
ret = snd_sof_init_trace_ipc(sdev);
498+
ret = snd_sof_enable_trace(sdev);
494499
if (ret < 0)
495500
goto table_err;
496501

@@ -510,7 +515,8 @@ int snd_sof_trace_update_pos(struct snd_sof_dev *sdev,
510515
if (!sdev->dtrace_is_supported)
511516
return 0;
512517

513-
if (sdev->dtrace_is_enabled && sdev->host_offset != posn->host_offset) {
518+
if (sdev->dtrace_state == SOF_DTRACE_ENABLED &&
519+
sdev->host_offset != posn->host_offset) {
514520
sdev->host_offset = posn->host_offset;
515521
wake_up(&sdev->trace_sleep);
516522
}
@@ -529,28 +535,29 @@ void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev)
529535
if (!sdev->dtrace_is_supported)
530536
return;
531537

532-
if (sdev->dtrace_is_enabled) {
538+
if (sdev->dtrace_state == SOF_DTRACE_ENABLED) {
533539
sdev->dtrace_error = true;
534540
wake_up(&sdev->trace_sleep);
535541
}
536542
}
537543
EXPORT_SYMBOL(snd_sof_trace_notify_for_error);
538544

539-
void snd_sof_release_trace(struct snd_sof_dev *sdev)
545+
static void snd_sof_release_trace(struct snd_sof_dev *sdev, bool only_stop)
540546
{
541547
struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
542548
struct sof_ipc_fw_version *v = &ready->version;
543549
struct sof_ipc_cmd_hdr hdr;
544550
struct sof_ipc_reply ipc_reply;
545551
int ret;
546552

547-
if (!sdev->dtrace_is_supported || !sdev->dtrace_is_enabled)
553+
if (!sdev->dtrace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED)
548554
return;
549555

550556
ret = snd_sof_dma_trace_trigger(sdev, SNDRV_PCM_TRIGGER_STOP);
551557
if (ret < 0)
552558
dev_err(sdev->dev,
553559
"error: snd_sof_dma_trace_trigger: stop: %d\n", ret);
560+
sdev->dtrace_state = SOF_DTRACE_STOPPED;
554561

555562
/*
556563
* stop and free trace DMA in the DSP. TRACE_DMA_FREE is only supported from
@@ -566,23 +573,46 @@ void snd_sof_release_trace(struct snd_sof_dev *sdev)
566573
dev_err(sdev->dev, "DMA_TRACE_FREE failed with error: %d\n", ret);
567574
}
568575

576+
if (only_stop)
577+
goto out;
578+
569579
ret = snd_sof_dma_trace_release(sdev);
570580
if (ret < 0)
571581
dev_err(sdev->dev,
572582
"error: fail in snd_sof_dma_trace_release %d\n", ret);
573583

574-
sdev->dtrace_is_enabled = false;
584+
sdev->dtrace_state = SOF_DTRACE_DISABLED;
585+
586+
out:
575587
sdev->dtrace_draining = true;
576588
wake_up(&sdev->trace_sleep);
577589
}
578-
EXPORT_SYMBOL(snd_sof_release_trace);
590+
591+
int snd_sof_trace_suspend(struct snd_sof_dev *sdev, int pm_state)
592+
{
593+
if (pm_state == SOF_DSP_PM_D0)
594+
snd_sof_release_trace(sdev, 1);
595+
else
596+
snd_sof_release_trace(sdev, 0);
597+
598+
/* always return 0 */
599+
return 0;
600+
}
601+
EXPORT_SYMBOL(snd_sof_trace_suspend);
602+
603+
int snd_sof_trace_resume(struct snd_sof_dev *sdev)
604+
{
605+
return snd_sof_enable_trace(sdev);
606+
}
607+
EXPORT_SYMBOL(snd_sof_trace_resume);
579608

580609
void snd_sof_free_trace(struct snd_sof_dev *sdev)
581610
{
582611
if (!sdev->dtrace_is_supported)
583612
return;
584613

585-
snd_sof_release_trace(sdev);
614+
/* release trace */
615+
snd_sof_release_trace(sdev, 0);
586616

587617
if (sdev->dma_trace_pages) {
588618
snd_dma_free_pages(&sdev->dmatb);

0 commit comments

Comments
 (0)