diff options
| author | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
|---|---|---|
| committer | Rodrigo Vivi <[email protected]> | 2018-07-23 09:13:12 -0700 | 
| commit | c74a7469f97c0f40b46e82ee979f9fb1bb6e847c (patch) | |
| tree | f2690a1a916b73ef94657fbf0e0141ae57701825 /sound/soc/intel/skylake/skl-topology.c | |
| parent | 6f15a7de86c8cf2dc09fc9e6d07047efa40ef809 (diff) | |
| parent | 500775074f88d9cf5416bed2ca19592812d62c41 (diff) | |
Merge drm/drm-next into drm-intel-next-queued
We need a backmerge to get DP_DPCD_REV_14 before we push other
i915 changes to dinq that could break compilation.
Signed-off-by: Rodrigo Vivi <[email protected]>
Diffstat (limited to 'sound/soc/intel/skylake/skl-topology.c')
| -rw-r--r-- | sound/soc/intel/skylake/skl-topology.c | 183 | 
1 files changed, 178 insertions, 5 deletions
| diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 3b1dca419883..fcdc716754b6 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c @@ -19,14 +19,15 @@  #include <linux/slab.h>  #include <linux/types.h>  #include <linux/firmware.h> +#include <linux/uuid.h>  #include <sound/soc.h>  #include <sound/soc-topology.h>  #include <uapi/sound/snd_sst_tokens.h> +#include <uapi/sound/skl-tplg-interface.h>  #include "skl-sst-dsp.h"  #include "skl-sst-ipc.h"  #include "skl-topology.h"  #include "skl.h" -#include "skl-tplg-interface.h"  #include "../common/sst-dsp.h"  #include "../common/sst-dsp-priv.h" @@ -2427,8 +2428,10 @@ static int skl_tplg_get_token(struct device *dev,  	case SKL_TKN_U8_DYN_IN_PIN:  		if (!mconfig->m_in_pin) -			mconfig->m_in_pin = devm_kzalloc(dev, MAX_IN_QUEUE * -					sizeof(*mconfig->m_in_pin), GFP_KERNEL); +			mconfig->m_in_pin = +				devm_kcalloc(dev, MAX_IN_QUEUE, +					     sizeof(*mconfig->m_in_pin), +					     GFP_KERNEL);  		if (!mconfig->m_in_pin)  			return -ENOMEM; @@ -2438,8 +2441,10 @@ static int skl_tplg_get_token(struct device *dev,  	case SKL_TKN_U8_DYN_OUT_PIN:  		if (!mconfig->m_out_pin) -			mconfig->m_out_pin = devm_kzalloc(dev, MAX_IN_QUEUE * -					sizeof(*mconfig->m_in_pin), GFP_KERNEL); +			mconfig->m_out_pin = +				devm_kcalloc(dev, MAX_IN_QUEUE, +					     sizeof(*mconfig->m_in_pin), +					     GFP_KERNEL);  		if (!mconfig->m_out_pin)  			return -ENOMEM; @@ -2724,6 +2729,167 @@ static int skl_tplg_get_desc_blocks(struct device *dev,  	return -EINVAL;  } +/* Functions to parse private data from configuration file format v4 */ + +/* + * Add pipeline from topology binary into driver pipeline list + * + * If already added we return that instance + * Otherwise we create a new instance and add into driver list + */ +static int skl_tplg_add_pipe_v4(struct device *dev, +				struct skl_module_cfg *mconfig, struct skl *skl, +				struct skl_dfw_v4_pipe *dfw_pipe) +{ +	struct skl_pipeline *ppl; +	struct skl_pipe *pipe; +	struct skl_pipe_params *params; + +	list_for_each_entry(ppl, &skl->ppl_list, node) { +		if (ppl->pipe->ppl_id == dfw_pipe->pipe_id) { +			mconfig->pipe = ppl->pipe; +			return 0; +		} +	} + +	ppl = devm_kzalloc(dev, sizeof(*ppl), GFP_KERNEL); +	if (!ppl) +		return -ENOMEM; + +	pipe = devm_kzalloc(dev, sizeof(*pipe), GFP_KERNEL); +	if (!pipe) +		return -ENOMEM; + +	params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL); +	if (!params) +		return -ENOMEM; + +	pipe->ppl_id = dfw_pipe->pipe_id; +	pipe->memory_pages = dfw_pipe->memory_pages; +	pipe->pipe_priority = dfw_pipe->pipe_priority; +	pipe->conn_type = dfw_pipe->conn_type; +	pipe->state = SKL_PIPE_INVALID; +	pipe->p_params = params; +	INIT_LIST_HEAD(&pipe->w_list); + +	ppl->pipe = pipe; +	list_add(&ppl->node, &skl->ppl_list); + +	mconfig->pipe = pipe; + +	return 0; +} + +static void skl_fill_module_pin_info_v4(struct skl_dfw_v4_module_pin *dfw_pin, +					struct skl_module_pin *m_pin, +					bool is_dynamic, int max_pin) +{ +	int i; + +	for (i = 0; i < max_pin; i++) { +		m_pin[i].id.module_id = dfw_pin[i].module_id; +		m_pin[i].id.instance_id = dfw_pin[i].instance_id; +		m_pin[i].in_use = false; +		m_pin[i].is_dynamic = is_dynamic; +		m_pin[i].pin_state = SKL_PIN_UNBIND; +	} +} + +static void skl_tplg_fill_fmt_v4(struct skl_module_pin_fmt *dst_fmt, +				 struct skl_dfw_v4_module_fmt *src_fmt, +				 int pins) +{ +	int i; + +	for (i = 0; i < pins; i++) { +		dst_fmt[i].fmt.channels  = src_fmt[i].channels; +		dst_fmt[i].fmt.s_freq = src_fmt[i].freq; +		dst_fmt[i].fmt.bit_depth = src_fmt[i].bit_depth; +		dst_fmt[i].fmt.valid_bit_depth = src_fmt[i].valid_bit_depth; +		dst_fmt[i].fmt.ch_cfg = src_fmt[i].ch_cfg; +		dst_fmt[i].fmt.ch_map = src_fmt[i].ch_map; +		dst_fmt[i].fmt.interleaving_style = +						src_fmt[i].interleaving_style; +		dst_fmt[i].fmt.sample_type = src_fmt[i].sample_type; +	} +} + +static int skl_tplg_get_pvt_data_v4(struct snd_soc_tplg_dapm_widget *tplg_w, +				    struct skl *skl, struct device *dev, +				    struct skl_module_cfg *mconfig) +{ +	struct skl_dfw_v4_module *dfw = +				(struct skl_dfw_v4_module *)tplg_w->priv.data; +	int ret; + +	dev_dbg(dev, "Parsing Skylake v4 widget topology data\n"); + +	ret = guid_parse(dfw->uuid, (guid_t *)mconfig->guid); +	if (ret) +		return ret; +	mconfig->id.module_id = -1; +	mconfig->id.instance_id = dfw->instance_id; +	mconfig->module->resources[0].cps = dfw->max_mcps; +	mconfig->module->resources[0].ibs = dfw->ibs; +	mconfig->module->resources[0].obs = dfw->obs; +	mconfig->core_id = dfw->core_id; +	mconfig->module->max_input_pins = dfw->max_in_queue; +	mconfig->module->max_output_pins = dfw->max_out_queue; +	mconfig->module->loadable = dfw->is_loadable; +	skl_tplg_fill_fmt_v4(mconfig->module->formats[0].inputs, dfw->in_fmt, +			     MAX_IN_QUEUE); +	skl_tplg_fill_fmt_v4(mconfig->module->formats[0].outputs, dfw->out_fmt, +			     MAX_OUT_QUEUE); + +	mconfig->params_fixup = dfw->params_fixup; +	mconfig->converter = dfw->converter; +	mconfig->m_type = dfw->module_type; +	mconfig->vbus_id = dfw->vbus_id; +	mconfig->module->resources[0].is_pages = dfw->mem_pages; + +	ret = skl_tplg_add_pipe_v4(dev, mconfig, skl, &dfw->pipe); +	if (ret) +		return ret; + +	mconfig->dev_type = dfw->dev_type; +	mconfig->hw_conn_type = dfw->hw_conn_type; +	mconfig->time_slot = dfw->time_slot; +	mconfig->formats_config.caps_size = dfw->caps.caps_size; + +	mconfig->m_in_pin = devm_kcalloc(dev, +				MAX_IN_QUEUE, sizeof(*mconfig->m_in_pin), +				GFP_KERNEL); +	if (!mconfig->m_in_pin) +		return -ENOMEM; + +	mconfig->m_out_pin = devm_kcalloc(dev, +				MAX_OUT_QUEUE, sizeof(*mconfig->m_out_pin), +				GFP_KERNEL); +	if (!mconfig->m_out_pin) +		return -ENOMEM; + +	skl_fill_module_pin_info_v4(dfw->in_pin, mconfig->m_in_pin, +				    dfw->is_dynamic_in_pin, +				    mconfig->module->max_input_pins); +	skl_fill_module_pin_info_v4(dfw->out_pin, mconfig->m_out_pin, +				    dfw->is_dynamic_out_pin, +				    mconfig->module->max_output_pins); + +	if (mconfig->formats_config.caps_size) { +		mconfig->formats_config.set_params = dfw->caps.set_params; +		mconfig->formats_config.param_id = dfw->caps.param_id; +		mconfig->formats_config.caps = +		devm_kzalloc(dev, mconfig->formats_config.caps_size, +			     GFP_KERNEL); +		if (!mconfig->formats_config.caps) +			return -ENOMEM; +		memcpy(mconfig->formats_config.caps, dfw->caps.caps, +		       dfw->caps.caps_size); +	} + +	return 0; +} +  /*   * Parse the private data for the token and corresponding value.   * The private data can have multiple data blocks. So, a data block @@ -2739,6 +2905,13 @@ static int skl_tplg_get_pvt_data(struct snd_soc_tplg_dapm_widget *tplg_w,  	char *data;  	int ret; +	/* +	 * v4 configuration files have a valid UUID at the start of +	 * the widget's private data. +	 */ +	if (uuid_is_valid((char *)tplg_w->priv.data)) +		return skl_tplg_get_pvt_data_v4(tplg_w, skl, dev, mconfig); +  	/* Read the NUM_DATA_BLOCKS descriptor */  	array = (struct snd_soc_tplg_vendor_array *)tplg_w->priv.data;  	ret = skl_tplg_get_desc_blocks(dev, array); |