ASoC: SOF: Intel: CNL: add support for sending compact IPC
authorKeyon Jie <yang.jie@linux.intel.com>
Fri, 25 Oct 2019 22:41:14 +0000 (17:41 -0500)
committerMark Brown <broonie@kernel.org>
Mon, 28 Oct 2019 14:44:37 +0000 (14:44 +0000)
For compact IPCs, we will send the IPC header/command via the HIPCIDR
register and the first 32bit payload via the HIPCIDD register, no
mailbox will be used.

Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20191025224122.7718-19-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda.h

index 982b81a..0e1e265 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "../ops.h"
 #include "hda.h"
+#include "hda-ipc.h"
 
 static const struct snd_sof_debugfs_map cnl_dsp_debugfs[] = {
        {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
@@ -150,14 +151,45 @@ static void cnl_ipc_dsp_done(struct snd_sof_dev *sdev)
                                CNL_DSP_REG_HIPCCTL_DONE);
 }
 
+static bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg,
+                                    u32 *dr, u32 *dd)
+{
+       struct sof_ipc_pm_gate *pm_gate;
+
+       if (msg->header == (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE)) {
+               pm_gate = msg->msg_data;
+
+               /* send the compact message via the primary register */
+               *dr = HDA_IPC_MSG_COMPACT | HDA_IPC_PM_GATE;
+
+               /* send payload via the extended data register */
+               *dd = pm_gate->flags;
+
+               return true;
+       }
+
+       return false;
+}
+
 static int cnl_ipc_send_msg(struct snd_sof_dev *sdev,
                            struct snd_sof_ipc_msg *msg)
 {
-       /* send the message */
-       sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
-                         msg->msg_size);
-       snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR,
-                         CNL_DSP_REG_HIPCIDR_BUSY);
+       u32 dr = 0;
+       u32 dd = 0;
+
+       if (cnl_compact_ipc_compress(msg, &dr, &dd)) {
+               /* send the message via IPC registers */
+               snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDD,
+                                 dd);
+               snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR,
+                                 CNL_DSP_REG_HIPCIDR_BUSY | dr);
+       } else {
+               /* send the message via mailbox */
+               sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
+                                 msg->msg_size);
+               snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR,
+                                 CNL_DSP_REG_HIPCIDR_BUSY);
+       }
 
        return 0;
 }
index 99ec602..52a87a4 100644 (file)
 #define CNL_DSP_REG_HIPCTDD            (CNL_DSP_IPC_BASE + 0x08)
 #define CNL_DSP_REG_HIPCIDR            (CNL_DSP_IPC_BASE + 0x10)
 #define CNL_DSP_REG_HIPCIDA            (CNL_DSP_IPC_BASE + 0x14)
+#define CNL_DSP_REG_HIPCIDD            (CNL_DSP_IPC_BASE + 0x18)
 #define CNL_DSP_REG_HIPCCTL            (CNL_DSP_IPC_BASE + 0x28)
 
 /*  HIPCI */