1010
1111#define MAX_FW_STATE_STRING_LEN 128
1212
13+ #define SOF_DSP_PM_D0I0 0
14+ #define SOF_DSP_PM_D0I3 1
15+
1316/*
1417 * set dsp power state op by writing the requested power state.
1518 * ex: echo D3 > dsp_power_state
1619 */
1720static int sof_dsp_ops_set_power_state (struct snd_sof_dev * sdev , char * state )
1821{
19- /* only D3 supported for now */
20- if (strcmp (state , "D3" )) {
21- dev_err (sdev -> dev , "Unsupported state %s\n" , state );
22+ const struct sof_ipc_pm_ops * pm_ops = sof_ipc_get_ops (sdev , pm );
23+ struct sof_dsp_power_state target_state ;
24+ int ret ;
25+
26+ /* Only D3/D0IO/D0I3 states supported */
27+ if (strcmp (state , "D3" ) && strcmp (state , "D0I3" ) && strcmp (state , "D0I0" )) {
28+ dev_err (sdev -> dev , "Unsupported DSP PM state %s\n" , state );
2229 return - EINVAL ;
2330 }
2431
25- /* power off the DSP */
26- if (sdev -> dsp_power_state .state == SOF_DSP_PM_D0 ) {
27- const struct sof_ipc_pm_ops * pm_ops = sof_ipc_get_ops (sdev , pm );
28- struct sof_dsp_power_state target_state = {
29- .state = SOF_DSP_PM_D3 ,
30- };
31- int ret ;
32+ /* put the DSP in D3 state */
33+ if (!strcmp (state , "D3" )) {
34+ if (sdev -> dsp_power_state .state == SOF_DSP_PM_D3 )
35+ return 0 ;
36+
37+ target_state .state = SOF_DSP_PM_D3 ;
3238
3339 /* notify DSP of upcoming power down */
3440 if (pm_ops && pm_ops -> ctx_save ) {
@@ -43,9 +49,18 @@ static int sof_dsp_ops_set_power_state(struct snd_sof_dev *sdev, char *state)
4349
4450 sdev -> enabled_cores_mask = 0 ;
4551 sof_set_fw_state (sdev , SOF_FW_BOOT_NOT_STARTED );
52+
53+ return 0 ;
4654 }
4755
48- return 0 ;
56+ /* handle D0I0/D0I3 transitions */
57+ target_state .state = SOF_DSP_PM_D0 ;
58+ if (!strcmp (state , "D0I3" ))
59+ target_state .substate = SOF_DSP_PM_D0I3 ;
60+ else
61+ target_state .substate = SOF_DSP_PM_D0I0 ;
62+
63+ return snd_sof_dsp_set_power_state (sdev , & target_state );
4964}
5065
5166static int sof_dsp_ops_trace_init (struct snd_sof_dev * sdev , bool init )
@@ -175,7 +190,16 @@ static ssize_t sof_dsp_ops_tester_dfs_read(struct file *file, char __user *buffe
175190 } else if (!strcmp (dentry -> d_name .name , "dsp_power_state" )) {
176191 switch (sdev -> dsp_power_state .state ) {
177192 case SOF_DSP_PM_D0 :
178- string = "D0\n" ;
193+ switch (sdev -> dsp_power_state .substate ) {
194+ case SOF_DSP_PM_D0I0 :
195+ string = "D0I0\n" ;
196+ break ;
197+ case SOF_DSP_PM_D0I3 :
198+ string = "D0I3\n" ;
199+ break ;
200+ default :
201+ break ;
202+ }
179203 break ;
180204 case SOF_DSP_PM_D3 :
181205 string = "D3\n" ;
0 commit comments