ASoC: Intel: Skylake: Add support for LPMode
authorVinod Koul <vinod.koul@intel.com>
Thu, 3 Nov 2016 11:37:18 +0000 (17:07 +0530)
committerMark Brown <broonie@kernel.org>
Thu, 3 Nov 2016 17:14:22 +0000 (11:14 -0600)
For D0i3, we need to tell DSP to run the pipelines in LP mode. This
information is kept in topology and passed to driver as an attribute
for pipe.

So add a new tuple for lpmode and program the pipe based on value set.

Signed-off-by: Jayachandran B <jayachandran.b@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
include/uapi/sound/snd_sst_tokens.h
sound/soc/intel/skylake/skl-messages.c
sound/soc/intel/skylake/skl-sst-ipc.c
sound/soc/intel/skylake/skl-sst-ipc.h
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.h

index 1ee2e943d66a319c6d0536b9deb96b3ea95c5be9..f4b8b34de51938c3d5fd293255158b993b5637d3 100644 (file)
  *
  * %SKL_TKN_STR_LIB_NAME:       Specifies the library name
  *
+ * %SKL_TKN_U32_PMODE:         Specifies the power mode for pipe
+ *
  * module_id and loadable flags dont have tokens as these values will be
  * read from the DSP FW manifest
  */
@@ -208,7 +210,8 @@ enum SKL_TKNS {
        SKL_TKN_U32_PROC_DOMAIN,
        SKL_TKN_U32_LIB_COUNT,
        SKL_TKN_STR_LIB_NAME,
-       SKL_TKN_MAX = SKL_TKN_STR_LIB_NAME,
+       SKL_TKN_U32_PMODE,
+       SKL_TKN_MAX = SKL_TKN_U32_PMODE,
 };
 
 #endif
index 805b7f2173f3ec6163d9de9728d0b099d9a3a9a1..87fc647fa04cda4dc40ab1cce0a50a4a0e721f3e 100644 (file)
@@ -1042,7 +1042,8 @@ int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe)
        dev_dbg(ctx->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id);
 
        ret = skl_ipc_create_pipeline(&ctx->ipc, pipe->memory_pages,
-                               pipe->pipe_priority, pipe->ppl_id);
+                               pipe->pipe_priority, pipe->ppl_id,
+                               pipe->lp_mode);
        if (ret < 0) {
                dev_err(ctx->dev, "Failed to create pipeline\n");
                return ret;
index 087b8d6e7186870cf800f45915c40c74635fed9b..734408a34a240b1078fe915b20dd334e0a5304e7 100644 (file)
 #define IPC_INSTANCE_ID(x)             (((x) & IPC_INSTANCE_ID_MASK) \
                                        << IPC_INSTANCE_ID_SHIFT)
 
+#define IPC_PPL_LP_MODE_SHIFT           0
+#define IPC_PPL_LP_MODE_MASK            0x1
+#define IPC_PPL_LP_MODE(x)              (((x) & IPC_PPL_LP_MODE_MASK) \
+                                       << IPC_PPL_LP_MODE_SHIFT)
+
 /* Set pipeline state message */
 #define IPC_PPL_STATE_SHIFT            0
 #define IPC_PPL_STATE_MASK             0x1F
@@ -559,7 +564,7 @@ void skl_ipc_free(struct sst_generic_ipc *ipc)
 }
 
 int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
-               u16 ppl_mem_size, u8 ppl_type, u8 instance_id)
+               u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode)
 {
        struct skl_ipc_header header = {0};
        u64 *ipc_header = (u64 *)(&header);
@@ -572,6 +577,8 @@ int skl_ipc_create_pipeline(struct sst_generic_ipc *ipc,
        header.primary |= IPC_PPL_TYPE(ppl_type);
        header.primary |= IPC_PPL_MEM_SIZE(ppl_mem_size);
 
+       header.extension = IPC_PPL_LP_MODE(lp_mode);
+
        dev_dbg(ipc->dev, "In %s header=%d\n", __func__, header.primary);
        ret = sst_ipc_tx_message_wait(ipc, *ipc_header, NULL, 0, NULL, 0);
        if (ret < 0) {
index a45c42046b64b689f02282a69a1734858473a92a..83bf1689f62e890150e47ea5f291454b57357dba 100644 (file)
@@ -148,7 +148,7 @@ struct skl_ipc_d0ix_msg {
 irqreturn_t skl_dsp_irq_thread_handler(int irq, void *context);
 
 int skl_ipc_create_pipeline(struct sst_generic_ipc *sst_ipc,
-               u16 ppl_mem_size, u8 ppl_type, u8 instance_id);
+               u16 ppl_mem_size, u8 ppl_type, u8 instance_id, u8 lp_mode);
 
 int skl_ipc_delete_pipeline(struct sst_generic_ipc *sst_ipc, u8 instance_id);
 
index b5b1934d85504e328c0821405386eb2f22e85675..9a7a008f66892a795f90a1576ea78dcf57208a46 100644 (file)
@@ -1519,6 +1519,10 @@ static int skl_tplg_fill_pipe_tkn(struct device *dev,
                pipe->memory_pages = tkn_val;
                break;
 
+       case SKL_TKN_U32_PMODE:
+               pipe->lp_mode = tkn_val;
+               break;
+
        default:
                dev_err(dev, "Token not handled %d\n", tkn);
                return -EINVAL;
@@ -1841,6 +1845,7 @@ static int skl_tplg_get_token(struct device *dev,
        case SKL_TKN_U32_PIPE_CONN_TYPE:
        case SKL_TKN_U32_PIPE_PRIORITY:
        case SKL_TKN_U32_PIPE_MEM_PGS:
+       case SKL_TKN_U32_PMODE:
                if (is_pipe_exists) {
                        ret = skl_tplg_fill_pipe_tkn(dev, mconfig->pipe,
                                        tkn_elem->token, tkn_elem->value);
index a519360f42a62d42b2c7a39b9ab8e0dac19bc28d..11fd0a4b66031c9eb77b7eb90aca1cad57283007 100644 (file)
@@ -279,6 +279,7 @@ struct skl_pipe {
        u8 pipe_priority;
        u16 conn_type;
        u32 memory_pages;
+       u8 lp_mode;
        struct skl_pipe_params *p_params;
        enum skl_pipe_state state;
        struct list_head w_list;