Commit a4ad42d2 authored by Kareem Shaik's avatar Kareem Shaik Committed by Mark Brown

ASoC: Intel: Skylake: Support multiple format configs

A module can have two kinds of set params, as per topology requirements.
For example, one pre-init and one post-init. But currently, there is
support for just one type, as the format_config.

This patch extends the format_configs to 4, so as to be able to support
pre-init, post-init and post-bind type of set params, for the same
module, simultaneously.
Signed-off-by: default avatarKareem Shaik <kareem.m.shaik@intel.com>
Signed-off-by: default avatarGustaw Lewandowski <gustaw.lewandowski@linux.intel.com>
Signed-off-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
Tested-by: default avatarLukasz Majczak <lma@semihalf.com>
Link: https://lore.kernel.org/r/20210818075742.1515155-9-cezary.rojewski@intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent e4e95d82
...@@ -233,6 +233,8 @@ ...@@ -233,6 +233,8 @@
* *
* %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry * %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry
* *
* %SKL_TKN_U32_FMT_CFG_IDX: Format config index
*
* module_id and loadable flags dont have tokens as these values will be * module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest * read from the DSP FW manifest
* *
...@@ -324,7 +326,9 @@ enum SKL_TKNS { ...@@ -324,7 +326,9 @@ enum SKL_TKNS {
SKL_TKN_U32_ASTATE_COUNT, SKL_TKN_U32_ASTATE_COUNT,
SKL_TKN_U32_ASTATE_KCPS, SKL_TKN_U32_ASTATE_KCPS,
SKL_TKN_U32_ASTATE_CLK_SRC, SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_U32_FMT_CFG_IDX = 96,
SKL_TKN_MAX = SKL_TKN_U32_FMT_CFG_IDX,
}; };
#endif #endif
...@@ -479,15 +479,15 @@ static void skl_set_base_module_format(struct skl_dev *skl, ...@@ -479,15 +479,15 @@ static void skl_set_base_module_format(struct skl_dev *skl,
static void skl_copy_copier_caps(struct skl_module_cfg *mconfig, static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
struct skl_cpr_cfg *cpr_mconfig) struct skl_cpr_cfg *cpr_mconfig)
{ {
if (mconfig->formats_config.caps_size == 0) if (mconfig->formats_config[SKL_PARAM_INIT].caps_size == 0)
return; return;
memcpy(cpr_mconfig->gtw_cfg.config_data, memcpy(cpr_mconfig->gtw_cfg.config_data,
mconfig->formats_config.caps, mconfig->formats_config[SKL_PARAM_INIT].caps,
mconfig->formats_config.caps_size); mconfig->formats_config[SKL_PARAM_INIT].caps_size);
cpr_mconfig->gtw_cfg.config_length = cpr_mconfig->gtw_cfg.config_length =
(mconfig->formats_config.caps_size) / 4; (mconfig->formats_config[SKL_PARAM_INIT].caps_size) / 4;
} }
#define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF #define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
...@@ -749,13 +749,12 @@ static void skl_set_algo_format(struct skl_dev *skl, ...@@ -749,13 +749,12 @@ static void skl_set_algo_format(struct skl_dev *skl,
struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg; struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg;
skl_set_base_module_format(skl, mconfig, base_cfg); skl_set_base_module_format(skl, mconfig, base_cfg);
if (mconfig->formats_config[SKL_PARAM_INIT].caps_size == 0)
if (mconfig->formats_config.caps_size == 0)
return; return;
memcpy(algo_mcfg->params, memcpy(algo_mcfg->params,
mconfig->formats_config.caps, mconfig->formats_config[SKL_PARAM_INIT].caps,
mconfig->formats_config.caps_size); mconfig->formats_config[SKL_PARAM_INIT].caps_size);
} }
...@@ -786,7 +785,7 @@ static u16 skl_get_module_param_size(struct skl_dev *skl, ...@@ -786,7 +785,7 @@ static u16 skl_get_module_param_size(struct skl_dev *skl,
switch (mconfig->m_type) { switch (mconfig->m_type) {
case SKL_MODULE_TYPE_COPIER: case SKL_MODULE_TYPE_COPIER:
param_size = sizeof(struct skl_cpr_cfg); param_size = sizeof(struct skl_cpr_cfg);
param_size += mconfig->formats_config.caps_size; param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
return param_size; return param_size;
case SKL_MODULE_TYPE_SRCINT: case SKL_MODULE_TYPE_SRCINT:
...@@ -797,7 +796,7 @@ static u16 skl_get_module_param_size(struct skl_dev *skl, ...@@ -797,7 +796,7 @@ static u16 skl_get_module_param_size(struct skl_dev *skl,
case SKL_MODULE_TYPE_ALGO: case SKL_MODULE_TYPE_ALGO:
param_size = sizeof(struct skl_base_cfg); param_size = sizeof(struct skl_base_cfg);
param_size += mconfig->formats_config.caps_size; param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
return param_size; return param_size;
case SKL_MODULE_TYPE_BASE_OUTFMT: case SKL_MODULE_TYPE_BASE_OUTFMT:
......
...@@ -292,7 +292,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, ...@@ -292,7 +292,7 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx]; struct skl_module_iface *m_iface = &m_cfg->module->formats[fmt_idx];
/* check if we already have blob */ /* check if we already have blob */
if (m_cfg->formats_config.caps_size > 0) if (m_cfg->formats_config[SKL_PARAM_INIT].caps_size > 0)
return 0; return 0;
dev_dbg(skl->dev, "Applying default cfg blob\n"); dev_dbg(skl->dev, "Applying default cfg blob\n");
...@@ -328,8 +328,8 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w, ...@@ -328,8 +328,8 @@ static int skl_tplg_update_be_blob(struct snd_soc_dapm_widget *w,
cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type, cfg = skl_get_ep_blob(skl, m_cfg->vbus_id, link_type,
s_fmt, ch, s_freq, dir, dev_type); s_fmt, ch, s_freq, dir, dev_type);
if (cfg) { if (cfg) {
m_cfg->formats_config.caps_size = cfg->size; m_cfg->formats_config[SKL_PARAM_INIT].caps_size = cfg->size;
m_cfg->formats_config.caps = (u32 *) &cfg->caps; m_cfg->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps;
} else { } else {
dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n", dev_err(skl->dev, "Blob NULL for id %x type %d dirn %d\n",
m_cfg->vbus_id, link_type, dir); m_cfg->vbus_id, link_type, dir);
...@@ -386,9 +386,9 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w, ...@@ -386,9 +386,9 @@ static int skl_tplg_set_module_params(struct snd_soc_dapm_widget *w,
struct skl_algo_data *bc; struct skl_algo_data *bc;
struct skl_specific_cfg *sp_cfg; struct skl_specific_cfg *sp_cfg;
if (mconfig->formats_config.caps_size > 0 && if (mconfig->formats_config[SKL_PARAM_SET].caps_size > 0 &&
mconfig->formats_config.set_params == SKL_PARAM_SET) { mconfig->formats_config[SKL_PARAM_SET].set_params == SKL_PARAM_SET) {
sp_cfg = &mconfig->formats_config; sp_cfg = &mconfig->formats_config[SKL_PARAM_SET];
ret = skl_set_module_params(skl, sp_cfg->caps, ret = skl_set_module_params(skl, sp_cfg->caps,
sp_cfg->caps_size, sp_cfg->caps_size,
sp_cfg->param_id, mconfig); sp_cfg->param_id, mconfig);
...@@ -438,8 +438,10 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w) ...@@ -438,8 +438,10 @@ static int skl_tplg_set_module_init_data(struct snd_soc_dapm_widget *w)
if (bc->set_params != SKL_PARAM_INIT) if (bc->set_params != SKL_PARAM_INIT)
continue; continue;
mconfig->formats_config.caps = (u32 *)bc->params; mconfig->formats_config[SKL_PARAM_INIT].caps =
mconfig->formats_config.caps_size = bc->size; (u32 *)bc->params;
mconfig->formats_config[SKL_PARAM_INIT].caps_size =
bc->size;
break; break;
} }
...@@ -798,9 +800,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w, ...@@ -798,9 +800,10 @@ static int skl_tplg_set_module_bind_params(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
if (mconfig->formats_config.caps_size > 0 && if (mconfig->formats_config[SKL_PARAM_BIND].caps_size > 0 &&
mconfig->formats_config.set_params == SKL_PARAM_BIND) { mconfig->formats_config[SKL_PARAM_BIND].set_params ==
sp_cfg = &mconfig->formats_config; SKL_PARAM_BIND) {
sp_cfg = &mconfig->formats_config[SKL_PARAM_BIND];
ret = skl_set_module_params(skl, sp_cfg->caps, ret = skl_set_module_params(skl, sp_cfg->caps,
sp_cfg->caps_size, sp_cfg->caps_size,
sp_cfg->param_id, mconfig); sp_cfg->param_id, mconfig);
...@@ -1496,7 +1499,8 @@ static int skl_tplg_mic_control_get(struct snd_kcontrol *kcontrol, ...@@ -1496,7 +1499,8 @@ static int skl_tplg_mic_control_get(struct snd_kcontrol *kcontrol,
static int skl_fill_mic_sel_params(struct skl_module_cfg *mconfig, static int skl_fill_mic_sel_params(struct skl_module_cfg *mconfig,
struct skl_mic_sel_config *mic_cfg, struct device *dev) struct skl_mic_sel_config *mic_cfg, struct device *dev)
{ {
struct skl_specific_cfg *sp_cfg = &mconfig->formats_config; struct skl_specific_cfg *sp_cfg =
&mconfig->formats_config[SKL_PARAM_INIT];
sp_cfg->caps_size = sizeof(struct skl_mic_sel_config); sp_cfg->caps_size = sizeof(struct skl_mic_sel_config);
sp_cfg->set_params = SKL_PARAM_SET; sp_cfg->set_params = SKL_PARAM_SET;
...@@ -1849,8 +1853,8 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai, ...@@ -1849,8 +1853,8 @@ static int skl_tplg_be_fill_pipe_params(struct snd_soc_dai *dai,
pipe_fmt->freq, pipe->direction, pipe_fmt->freq, pipe->direction,
dev_type); dev_type);
if (cfg) { if (cfg) {
mconfig->formats_config.caps_size = cfg->size; mconfig->formats_config[SKL_PARAM_INIT].caps_size = cfg->size;
mconfig->formats_config.caps = (u32 *) &cfg->caps; mconfig->formats_config[SKL_PARAM_INIT].caps = (u32 *)&cfg->caps;
} else { } else {
dev_err(dai->dev, "Blob NULL for id:%d type:%d dirn:%d ch:%d, freq:%d, fmt:%d\n", dev_err(dai->dev, "Blob NULL for id:%d type:%d dirn:%d ch:%d, freq:%d, fmt:%d\n",
mconfig->vbus_id, link_type, params->stream, mconfig->vbus_id, link_type, params->stream,
...@@ -2567,19 +2571,26 @@ static int skl_tplg_get_token(struct device *dev, ...@@ -2567,19 +2571,26 @@ static int skl_tplg_get_token(struct device *dev,
break; break;
case SKL_TKN_U32_FMT_CFG_IDX:
if (tkn_elem->value > SKL_MAX_PARAMS_TYPES)
return -EINVAL;
mconfig->fmt_cfg_idx = tkn_elem->value;
break;
case SKL_TKN_U32_CAPS_SIZE: case SKL_TKN_U32_CAPS_SIZE:
mconfig->formats_config.caps_size = mconfig->formats_config[mconfig->fmt_cfg_idx].caps_size =
tkn_elem->value; tkn_elem->value;
break; break;
case SKL_TKN_U32_CAPS_SET_PARAMS: case SKL_TKN_U32_CAPS_SET_PARAMS:
mconfig->formats_config.set_params = mconfig->formats_config[mconfig->fmt_cfg_idx].set_params =
tkn_elem->value; tkn_elem->value;
break; break;
case SKL_TKN_U32_CAPS_PARAMS_ID: case SKL_TKN_U32_CAPS_PARAMS_ID:
mconfig->formats_config.param_id = mconfig->formats_config[mconfig->fmt_cfg_idx].param_id =
tkn_elem->value; tkn_elem->value;
break; break;
...@@ -2793,6 +2804,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, ...@@ -2793,6 +2804,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
struct skl_dfw_v4_module *dfw = struct skl_dfw_v4_module *dfw =
(struct skl_dfw_v4_module *)tplg_w->priv.data; (struct skl_dfw_v4_module *)tplg_w->priv.data;
int ret; int ret;
int idx = mconfig->fmt_cfg_idx;
dev_dbg(dev, "Parsing Skylake v4 widget topology data\n"); dev_dbg(dev, "Parsing Skylake v4 widget topology data\n");
...@@ -2826,7 +2838,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, ...@@ -2826,7 +2838,7 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
mconfig->dev_type = dfw->dev_type; mconfig->dev_type = dfw->dev_type;
mconfig->hw_conn_type = dfw->hw_conn_type; mconfig->hw_conn_type = dfw->hw_conn_type;
mconfig->time_slot = dfw->time_slot; mconfig->time_slot = dfw->time_slot;
mconfig->formats_config.caps_size = dfw->caps.caps_size; mconfig->formats_config[idx].caps_size = dfw->caps.caps_size;
mconfig->m_in_pin = devm_kcalloc(dev, mconfig->m_in_pin = devm_kcalloc(dev,
MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin), MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin),
...@@ -2847,21 +2859,39 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, ...@@ -2847,21 +2859,39 @@ static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w,
dfw->is_dynamic_out_pin, dfw->is_dynamic_out_pin,
mconfig->module->max_output_pins); mconfig->module->max_output_pins);
if (mconfig->formats_config.caps_size) { if (mconfig->formats_config[idx].caps_size) {
mconfig->formats_config.set_params = dfw->caps.set_params; mconfig->formats_config[idx].set_params = dfw->caps.set_params;
mconfig->formats_config.param_id = dfw->caps.param_id; mconfig->formats_config[idx].param_id = dfw->caps.param_id;
mconfig->formats_config.caps = mconfig->formats_config[idx].caps =
devm_kzalloc(dev, mconfig->formats_config.caps_size, devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
GFP_KERNEL); GFP_KERNEL);
if (!mconfig->formats_config.caps) if (!mconfig->formats_config[idx].caps)
return -ENOMEM; return -ENOMEM;
memcpy(mconfig->formats_config.caps, dfw->caps.caps, memcpy(mconfig->formats_config[idx].caps, dfw->caps.caps,
dfw->caps.caps_size); dfw->caps.caps_size);
} }
return 0; return 0;
} }
static int skl_tplg_get_caps_data(struct device *dev, char *data,
struct skl_module_cfg *mconfig)
{
int idx = mconfig->fmt_cfg_idx;
if (mconfig->formats_config[idx].caps_size > 0) {
mconfig->formats_config[idx].caps =
devm_kzalloc(dev, mconfig->formats_config[idx].caps_size,
GFP_KERNEL);
if (!mconfig->formats_config[idx].caps)
return -ENOMEM;
memcpy(mconfig->formats_config[idx].caps, data,
mconfig->formats_config[idx].caps_size);
}
return mconfig->formats_config[idx].caps_size;
}
/* /*
* Parse the private data for the token and corresponding value. * Parse the private data for the token and corresponding value.
* The private data can have multiple data blocks. So, a data block * The private data can have multiple data blocks. So, a data block
...@@ -2922,18 +2952,14 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w, ...@@ -2922,18 +2952,14 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,
if (block_type == SKL_TYPE_TUPLE) { if (block_type == SKL_TYPE_TUPLE) {
ret = skl_tplg_get_tokens(dev, data, ret = skl_tplg_get_tokens(dev, data,
skl, mconfig, block_size); skl, mconfig, block_size);
} else {
ret = skl_tplg_get_caps_data(dev, data, mconfig);
}
if (ret < 0) if (ret < 0)
return ret; return ret;
--num_blocks; --num_blocks;
} else {
if (mconfig->formats_config.caps_size > 0)
memcpy(mconfig->formats_config.caps, data,
mconfig->formats_config.caps_size);
--num_blocks;
ret = mconfig->formats_config.caps_size;
}
off += ret; off += ret;
} }
...@@ -3024,6 +3050,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index, ...@@ -3024,6 +3050,9 @@ static int skl_tplg_widget_load(struct snd_soc_component *cmpnt, int index,
*/ */
mconfig->id.module_id = -1; mconfig->id.module_id = -1;
/* To provide backward compatibility, set default as SKL_PARAM_INIT */
mconfig->fmt_cfg_idx = SKL_PARAM_INIT;
/* Parse private data for tuples */ /* Parse private data for tuples */
ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig); ret = skl_tplg_get_pvt_data(tplg_w, skl, bus->dev, mconfig);
if (ret < 0) if (ret < 0)
......
...@@ -81,6 +81,8 @@ enum skl_s_freq { ...@@ -81,6 +81,8 @@ enum skl_s_freq {
SKL_FS_INVALID SKL_FS_INVALID
}; };
#define SKL_MAX_PARAMS_TYPES 4
enum skl_widget_type { enum skl_widget_type {
SKL_WIDGET_VMIXER = 1, SKL_WIDGET_VMIXER = 1,
SKL_WIDGET_MIXER = 2, SKL_WIDGET_MIXER = 2,
...@@ -371,6 +373,7 @@ struct skl_module_cfg { ...@@ -371,6 +373,7 @@ struct skl_module_cfg {
struct skl_module *module; struct skl_module *module;
int res_idx; int res_idx;
int fmt_idx; int fmt_idx;
int fmt_cfg_idx;
u8 domain; u8 domain;
bool homogenous_inputs; bool homogenous_inputs;
bool homogenous_outputs; bool homogenous_outputs;
...@@ -401,7 +404,7 @@ struct skl_module_cfg { ...@@ -401,7 +404,7 @@ struct skl_module_cfg {
enum skl_hw_conn_type hw_conn_type; enum skl_hw_conn_type hw_conn_type;
enum skl_module_state m_state; enum skl_module_state m_state;
struct skl_pipe *pipe; struct skl_pipe *pipe;
struct skl_specific_cfg formats_config; struct skl_specific_cfg formats_config[SKL_MAX_PARAMS_TYPES];
struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE]; struct skl_pipe_mcfg mod_cfg[SKL_MAX_MODULES_IN_PIPE];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment