@@ -405,6 +405,34 @@ static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value)
405
405
return 0 ;
406
406
}
407
407
408
+ /*
409
+ * d0i3 streaming is enabled if all the active streams can
410
+ * work in d0i3 state and playback is enabled
411
+ */
412
+ static bool hda_dsp_d0i3_streaming_applicable (struct snd_sof_dev * sdev )
413
+ {
414
+ struct snd_pcm_substream * substream ;
415
+ struct snd_sof_pcm * spcm ;
416
+ bool playback_active = false;
417
+ int dir ;
418
+
419
+ list_for_each_entry (spcm , & sdev -> pcm_list , list ) {
420
+ for_each_pcm_streams (dir ) {
421
+ substream = spcm -> stream [dir ].substream ;
422
+ if (!substream || !substream -> runtime )
423
+ continue ;
424
+
425
+ if (!spcm -> stream [dir ].d0i3_compatible )
426
+ return false;
427
+
428
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK )
429
+ playback_active = true;
430
+ }
431
+ }
432
+
433
+ return playback_active ;
434
+ }
435
+
408
436
static int hda_dsp_set_D0_state (struct snd_sof_dev * sdev ,
409
437
const struct sof_dsp_power_state * target_state )
410
438
{
@@ -446,6 +474,9 @@ static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev,
446
474
!hda_enable_trace_D0I3_S0 ||
447
475
sdev -> system_suspend_target != SOF_SUSPEND_NONE )
448
476
flags = HDA_PM_NO_DMA_TRACE ;
477
+
478
+ if (hda_dsp_d0i3_streaming_applicable (sdev ))
479
+ flags |= HDA_PM_PG_STREAMING ;
449
480
} else {
450
481
/* prevent power gating in D0I0 */
451
482
flags = HDA_PM_PPG ;
0 commit comments