@@ -40,6 +40,8 @@ static const struct snd_sof_debugfs_map cnl_dsp_debugfs[] = {
4040 {"dsp" , HDA_DSP_BAR , 0 , 0x10000 },
4141};
4242
43+ static int cnl_ipc_cmd_done (struct snd_sof_dev * sdev , int dir );
44+
4345static irqreturn_t cnl_ipc_irq_thread (int irq , void * context )
4446{
4547 struct snd_sof_dev * sdev = (struct snd_sof_dev * )context ;
@@ -69,20 +71,15 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
6971 CNL_DSP_REG_HIPCCTL ,
7072 CNL_DSP_REG_HIPCCTL_DONE , 0 );
7173
72- /* handle immediate reply from DSP core */
73- snd_sof_ipc_reply (sdev , msg );
74-
75- /* clear DONE bit - tell DSP we have completed the operation */
76- snd_sof_dsp_update_bits_forced (sdev , HDA_DSP_BAR ,
77- CNL_DSP_REG_HIPCIDA ,
78- CNL_DSP_REG_HIPCIDA_DONE ,
79- CNL_DSP_REG_HIPCIDA_DONE );
80-
81- /* unmask Done interrupt */
82- snd_sof_dsp_update_bits (sdev , HDA_DSP_BAR ,
83- CNL_DSP_REG_HIPCCTL ,
84- CNL_DSP_REG_HIPCCTL_DONE ,
85- CNL_DSP_REG_HIPCCTL_DONE );
74+ /*
75+ * handle immediate reply from DSP core. If the msg is
76+ * found, set done bit in cmd_done which is called at the
77+ * end of message processing function, else set it here
78+ * because the done bit can't be set in cmd_done function
79+ * which is triggered by msg
80+ */
81+ if (snd_sof_ipc_reply (sdev , msg ))
82+ cnl_ipc_cmd_done (sdev , SOF_IPC_DSP_REPLY );
8683
8784 ret = IRQ_HANDLED ;
8885 }
@@ -108,8 +105,10 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
108105 snd_sof_ipc_msgs_rx (sdev );
109106 }
110107
111- /* clear busy interrupt to tell dsp controller this */
112- /* interrupt has been accepted, not trigger it again */
108+ /*
109+ * clear busy interrupt to tell dsp controller this
110+ * interrupt has been accepted, not trigger it again
111+ */
113112 snd_sof_dsp_update_bits_forced (sdev , HDA_DSP_BAR ,
114113 CNL_DSP_REG_HIPCTDR ,
115114 CNL_DSP_REG_HIPCTDR_BUSY ,
@@ -132,23 +131,45 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
132131 return ret ;
133132}
134133
135- static int cnl_ipc_cmd_done (struct snd_sof_dev * sdev )
134+ static int cnl_ipc_cmd_done (struct snd_sof_dev * sdev , int dir )
136135{
137- /* set done bit to ack dsp the msg has been processed */
138- snd_sof_dsp_update_bits_forced (sdev , HDA_DSP_BAR ,
139- CNL_DSP_REG_HIPCTDA ,
140- CNL_DSP_REG_HIPCTDA_DONE ,
141- CNL_DSP_REG_HIPCTDA_DONE );
136+ if (dir == SOF_IPC_HOST_REPLY ) {
137+ /*
138+ * set done bit to ack dsp the msg has been
139+ * processed and send reply msg to dsp
140+ */
141+ snd_sof_dsp_update_bits_forced (sdev , HDA_DSP_BAR ,
142+ CNL_DSP_REG_HIPCTDA ,
143+ CNL_DSP_REG_HIPCTDA_DONE ,
144+ CNL_DSP_REG_HIPCTDA_DONE );
145+ } else {
146+ /*
147+ * set DONE bit - tell DSP we have received the reply msg
148+ * from DSP, and processed it, don't send more reply to host
149+ */
150+ snd_sof_dsp_update_bits_forced (sdev , HDA_DSP_BAR ,
151+ CNL_DSP_REG_HIPCIDA ,
152+ CNL_DSP_REG_HIPCIDA_DONE ,
153+ CNL_DSP_REG_HIPCIDA_DONE );
154+
155+ /* unmask Done interrupt */
156+ snd_sof_dsp_update_bits (sdev , HDA_DSP_BAR ,
157+ CNL_DSP_REG_HIPCCTL ,
158+ CNL_DSP_REG_HIPCCTL_DONE ,
159+ CNL_DSP_REG_HIPCCTL_DONE );
160+ }
142161
143162 return 0 ;
144163}
145164
146165static int cnl_ipc_is_ready (struct snd_sof_dev * sdev )
147166{
148- u64 val ;
167+ u64 busy , done ;
149168
150- val = snd_sof_dsp_read (sdev , HDA_DSP_BAR , CNL_DSP_REG_HIPCIDR );
151- if (val & CNL_DSP_REG_HIPCIDR_BUSY )
169+ busy = snd_sof_dsp_read (sdev , HDA_DSP_BAR , CNL_DSP_REG_HIPCIDR );
170+ done = snd_sof_dsp_read (sdev , HDA_DSP_BAR , CNL_DSP_REG_HIPCIDA );
171+ if ((busy & CNL_DSP_REG_HIPCIDR_BUSY ) ||
172+ (done & CNL_DSP_REG_HIPCIDA_DONE ))
152173 return 0 ;
153174
154175 return 1 ;
0 commit comments