2018-12-27 17:53:01 +08:00
|
|
|
From 471433a8e7d3a7f99730c682d4c792a09f7dd483 Mon Sep 17 00:00:00 2001
|
2018-10-16 02:05:43 +08:00
|
|
|
From: "Kareem,Shaik" <kareem.m.shaik@intel.com>
|
|
|
|
Date: Thu, 15 Jun 2017 13:25:09 +0530
|
2018-12-27 17:53:01 +08:00
|
|
|
Subject: [PATCH 179/296] ASoC: Intel: Skylake: Parse manifest data to fill DMA
|
2018-10-16 02:05:43 +08:00
|
|
|
control parameters
|
|
|
|
|
|
|
|
DMA control parameters are required in order to initialize or
|
|
|
|
modify DMA gateway configuration in ADSP Firmware. These parameters
|
|
|
|
are kept in the manifest data blocks and driver should read these
|
|
|
|
values from this manifest.
|
|
|
|
|
|
|
|
This patch parses manifest private data blocks and fill DMA control
|
|
|
|
configuration structure in driver accordingly.
|
|
|
|
|
|
|
|
Change-Id: Icb01a78c1869181681c7d82f49069dc666be4444
|
|
|
|
Signed-off-by: Kareem,Shaik <kareem.m.shaik@intel.com>
|
|
|
|
---
|
|
|
|
include/uapi/sound/snd_sst_tokens.h | 11 +++-
|
|
|
|
sound/soc/intel/skylake/skl-topology.c | 85 ++++++++++++++++++++++++--
|
|
|
|
sound/soc/intel/skylake/skl.h | 21 +++++++
|
|
|
|
3 files changed, 111 insertions(+), 6 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h
|
|
|
|
index 5d3d81af0c30..7c0149476820 100644
|
|
|
|
--- a/include/uapi/sound/snd_sst_tokens.h
|
|
|
|
+++ b/include/uapi/sound/snd_sst_tokens.h
|
|
|
|
@@ -243,6 +243,12 @@
|
|
|
|
* indicate if this endpoint is participating
|
|
|
|
* in aggregation.
|
|
|
|
*
|
|
|
|
+ * %SKL_TKN_U32_DMACTRL_CFG_IDX:
|
|
|
|
+ * Config index to fill up DMA control params
|
|
|
|
+ *
|
|
|
|
+ * %SKL_TKN_U32_DMACTRL_CFG_SIZE:
|
|
|
|
+ * Size information of DMA control params
|
|
|
|
+ *
|
|
|
|
* module_id and loadable flags dont have tokens as these values will be
|
|
|
|
* read from the DSP FW manifest
|
|
|
|
*
|
|
|
|
@@ -339,8 +345,9 @@ enum SKL_TKNS {
|
|
|
|
SKL_TKN_U32_AGG_LINK_ID,
|
|
|
|
SKL_TKN_U32_AGG_CH_MASK,
|
|
|
|
SKL_TKN_U32_AGG_ID,
|
|
|
|
-
|
|
|
|
- SKL_TKN_MAX = SKL_TKN_U32_AGG_ID,
|
|
|
|
+ SKL_TKN_U32_DMACTRL_CFG_IDX,
|
|
|
|
+ SKL_TKN_U32_DMACTRL_CFG_SIZE,
|
|
|
|
+ SKL_TKN_MAX = SKL_TKN_U32_DMACTRL_CFG_SIZE,
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c
|
2018-12-27 17:53:01 +08:00
|
|
|
index a1f88c3e2aa4..cd5640eac05a 100644
|
2018-10-16 02:05:43 +08:00
|
|
|
--- a/sound/soc/intel/skylake/skl-topology.c
|
|
|
|
+++ b/sound/soc/intel/skylake/skl-topology.c
|
2018-12-27 17:53:01 +08:00
|
|
|
@@ -3925,6 +3925,63 @@ static int skl_tplg_get_str_tkn(struct device *dev,
|
2018-10-16 02:05:43 +08:00
|
|
|
return tkn_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static int skl_tplg_mfest_fill_dmactrl(struct device *dev,
|
|
|
|
+ struct skl_dmactrl_config *dmactrl_cfg,
|
|
|
|
+ struct snd_soc_tplg_vendor_value_elem *tkn_elem)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ u32 cfg_idx = dmactrl_cfg->idx;
|
|
|
|
+ struct skl_dmctrl_hdr *hdr = &dmactrl_cfg->hdr[cfg_idx];
|
|
|
|
+
|
|
|
|
+ switch (tkn_elem->token) {
|
|
|
|
+ case SKL_TKN_U32_FMT_CH:
|
|
|
|
+ hdr->ch = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U32_FMT_FREQ:
|
|
|
|
+ hdr->freq = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U32_FMT_BIT_DEPTH:
|
|
|
|
+ hdr->fmt = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U32_PIPE_DIRECTION:
|
|
|
|
+ hdr->direction = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U8_TIME_SLOT:
|
|
|
|
+ hdr->tdm_slot = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U32_VBUS_ID:
|
|
|
|
+ hdr->vbus_id = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U32_DMACTRL_CFG_IDX:
|
|
|
|
+ dmactrl_cfg->idx = tkn_elem->value;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SKL_TKN_U32_DMACTRL_CFG_SIZE:
|
|
|
|
+ if (tkn_elem->value && !hdr->data) {
|
|
|
|
+ hdr->data = devm_kzalloc(dev,
|
|
|
|
+ tkn_elem->value, GFP_KERNEL);
|
|
|
|
+ if (!hdr->data)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ hdr->data_size = tkn_elem->value;
|
|
|
|
+ } else {
|
|
|
|
+ hdr->data_size = 0;
|
|
|
|
+ dev_err(dev, "Invalid dmactrl info \n");
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ dev_err(dev, "Invalid token %d\n", tkn_elem->token);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static int skl_tplg_manifest_fill_fmt(struct device *dev,
|
|
|
|
struct skl_module_iface *fmt,
|
|
|
|
struct snd_soc_tplg_vendor_value_elem *tkn_elem,
|
2018-12-27 17:53:01 +08:00
|
|
|
@@ -4163,8 +4220,17 @@ static int skl_tplg_get_int_tkn(struct device *dev,
|
2018-10-16 02:05:43 +08:00
|
|
|
case SKL_TKN_U32_FMT_SAMPLE_TYPE:
|
|
|
|
case SKL_TKN_U32_FMT_CH_MAP:
|
|
|
|
case SKL_TKN_MM_U32_INTF_PIN_ID:
|
|
|
|
- ret = skl_tplg_manifest_fill_fmt(dev, fmt, tkn_elem,
|
|
|
|
- dir, pin_idx);
|
|
|
|
+ case SKL_TKN_U32_PIPE_DIRECTION:
|
|
|
|
+ case SKL_TKN_U8_TIME_SLOT:
|
|
|
|
+ case SKL_TKN_U32_VBUS_ID:
|
|
|
|
+ case SKL_TKN_U32_DMACTRL_CFG_IDX:
|
|
|
|
+ case SKL_TKN_U32_DMACTRL_CFG_SIZE:
|
|
|
|
+ if (skl->modules)
|
|
|
|
+ ret = skl_tplg_manifest_fill_fmt(dev, fmt, tkn_elem,
|
|
|
|
+ dir, pin_idx);
|
|
|
|
+ else
|
|
|
|
+ ret = skl_tplg_mfest_fill_dmactrl(dev, &skl->cfg.dmactrl_cfg,
|
|
|
|
+ tkn_elem);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
break;
|
2018-12-27 17:53:01 +08:00
|
|
|
@@ -4267,8 +4333,9 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
|
2018-10-16 02:05:43 +08:00
|
|
|
{
|
|
|
|
struct snd_soc_tplg_vendor_array *array;
|
|
|
|
int num_blocks, block_size = 0, block_type, off = 0;
|
|
|
|
+ struct skl_dmctrl_hdr *dmactrl_hdr;
|
|
|
|
+ int cfg_idx, ret;
|
|
|
|
char *data;
|
|
|
|
- int ret;
|
|
|
|
|
|
|
|
/* Read the NUM_DATA_BLOCKS descriptor */
|
|
|
|
array = (struct snd_soc_tplg_vendor_array *)manifest->priv.data;
|
2018-12-27 17:53:01 +08:00
|
|
|
@@ -4313,7 +4380,17 @@ static int skl_tplg_get_manifest_data(struct snd_soc_tplg_manifest *manifest,
|
2018-10-16 02:05:43 +08:00
|
|
|
|
|
|
|
--num_blocks;
|
|
|
|
} else {
|
|
|
|
- return -EINVAL;
|
|
|
|
+ cfg_idx = skl->cfg.dmactrl_cfg.idx;
|
|
|
|
+ if (cfg_idx < SKL_MAX_DMACTRL) {
|
|
|
|
+ dmactrl_hdr = &skl->cfg.dmactrl_cfg.hdr[cfg_idx];
|
|
|
|
+ if (dmactrl_hdr->data && (dmactrl_hdr->data_size == block_size))
|
|
|
|
+ memcpy(dmactrl_hdr->data, data, block_size);
|
|
|
|
+ } else {
|
|
|
|
+ dev_err(dev, "error block_idx value exceeding %d\n", cfg_idx);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ ret = block_size;
|
|
|
|
+ --num_blocks;
|
|
|
|
}
|
|
|
|
off += ret;
|
|
|
|
}
|
|
|
|
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
|
|
|
|
index 2883d86d56fe..51cc193c3353 100644
|
|
|
|
--- a/sound/soc/intel/skylake/skl.h
|
|
|
|
+++ b/sound/soc/intel/skylake/skl.h
|
|
|
|
@@ -47,6 +47,8 @@
|
|
|
|
#define AZX_EM2_DUM_MASK (1 << 23)
|
|
|
|
|
|
|
|
#define AZX_REG_VS_EM2_L1SEN BIT(13)
|
|
|
|
+#define SKL_MAX_DMA_CFG 24
|
|
|
|
+#define SKL_MAX_DMACTRL 7
|
|
|
|
|
|
|
|
struct skl_dsp_resource {
|
|
|
|
u32 max_mcps;
|
|
|
|
@@ -67,7 +69,26 @@ struct skl_astate_config {
|
|
|
|
struct skl_astate_param astate_table[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
+struct skl_dmctrl_hdr {
|
|
|
|
+ u32 vbus_id;
|
|
|
|
+ u32 freq;
|
|
|
|
+ u32 tdm_slot;
|
|
|
|
+ u32 fmt;
|
|
|
|
+ u32 direction;
|
|
|
|
+ u32 ch;
|
|
|
|
+ u32 data_size;
|
|
|
|
+ u32 *data;
|
|
|
|
+} __packed;
|
|
|
|
+
|
|
|
|
+struct skl_dmactrl_config {
|
|
|
|
+ u32 type;
|
|
|
|
+ u32 size;
|
|
|
|
+ u32 idx;
|
|
|
|
+ struct skl_dmctrl_hdr hdr[SKL_MAX_DMACTRL];
|
|
|
|
+} __packed;
|
|
|
|
+
|
|
|
|
struct skl_fw_config {
|
|
|
|
+ struct skl_dmactrl_config dmactrl_cfg;
|
|
|
|
struct skl_astate_config *astate_cfg;
|
|
|
|
};
|
|
|
|
|
|
|
|
--
|
2018-12-27 17:53:01 +08:00
|
|
|
2.19.1
|
2018-10-16 02:05:43 +08:00
|
|
|
|