147d7195dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d255b095SJeeja KP /*
3d255b095SJeeja KP  *  skl-message.c - HDA DSP interface for FW registration, Pipe and Module
4d255b095SJeeja KP  *  configurations
5d255b095SJeeja KP  *
6d255b095SJeeja KP  *  Copyright (C) 2015 Intel Corp
7d255b095SJeeja KP  *  Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
8d255b095SJeeja KP  *	   Jeeja KP <jeeja.kp@intel.com>
9d255b095SJeeja KP  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10d255b095SJeeja KP  */
11d255b095SJeeja KP 
12d255b095SJeeja KP #include <linux/slab.h>
13d255b095SJeeja KP #include <linux/pci.h>
14d255b095SJeeja KP #include <sound/core.h>
15d255b095SJeeja KP #include <sound/pcm.h>
160c24fdc0SGuenter Roeck #include <uapi/sound/skl-tplg-interface.h>
17d255b095SJeeja KP #include "skl-sst-dsp.h"
18b003a345SGuneshwor Singh #include "cnl-sst-dsp.h"
19d255b095SJeeja KP #include "skl-sst-ipc.h"
20d255b095SJeeja KP #include "skl.h"
21d255b095SJeeja KP #include "../common/sst-dsp.h"
22d255b095SJeeja KP #include "../common/sst-dsp-priv.h"
2323db472bSJeeja KP #include "skl-topology.h"
24d255b095SJeeja KP 
skl_alloc_dma_buf(struct device * dev,struct snd_dma_buffer * dmab,size_t size)25d255b095SJeeja KP static int skl_alloc_dma_buf(struct device *dev,
26d255b095SJeeja KP 		struct snd_dma_buffer *dmab, size_t size)
27d255b095SJeeja KP {
28619a1f19STakashi Iwai 	return snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, dmab);
29d255b095SJeeja KP }
30d255b095SJeeja KP 
skl_free_dma_buf(struct device * dev,struct snd_dma_buffer * dmab)31d255b095SJeeja KP static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
32d255b095SJeeja KP {
33619a1f19STakashi Iwai 	snd_dma_free_pages(dmab);
34d255b095SJeeja KP 	return 0;
35d255b095SJeeja KP }
36d255b095SJeeja KP 
379452314dSPradeep Tewani #define SKL_ASTATE_PARAM_ID	4
389452314dSPradeep Tewani 
skl_dsp_set_astate_cfg(struct skl_dev * skl,u32 cnt,void * data)39bcc2a2dcSCezary Rojewski void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data)
409452314dSPradeep Tewani {
419452314dSPradeep Tewani 	struct skl_ipc_large_config_msg	msg = {0};
429452314dSPradeep Tewani 
439452314dSPradeep Tewani 	msg.large_param_id = SKL_ASTATE_PARAM_ID;
449452314dSPradeep Tewani 	msg.param_data_size = (cnt * sizeof(struct skl_astate_param) +
459452314dSPradeep Tewani 				sizeof(cnt));
469452314dSPradeep Tewani 
47bcc2a2dcSCezary Rojewski 	skl_ipc_set_large_config(&skl->ipc, &msg, data);
489452314dSPradeep Tewani }
499452314dSPradeep Tewani 
skl_dsp_setup_spib(struct device * dev,unsigned int size,int stream_tag,int enable)5092eb4f62SJeeja KP static int skl_dsp_setup_spib(struct device *dev, unsigned int size,
5192eb4f62SJeeja KP 				int stream_tag, int enable)
5292eb4f62SJeeja KP {
5376f56faeSRakesh Ughreja 	struct hdac_bus *bus = dev_get_drvdata(dev);
5492eb4f62SJeeja KP 	struct hdac_stream *stream = snd_hdac_get_stream(bus,
5592eb4f62SJeeja KP 			SNDRV_PCM_STREAM_PLAYBACK, stream_tag);
5692eb4f62SJeeja KP 
5792eb4f62SJeeja KP 	if (!stream)
5892eb4f62SJeeja KP 		return -EINVAL;
5992eb4f62SJeeja KP 
6092eb4f62SJeeja KP 	/* enable/disable SPIB for this hdac stream */
6162582341SPierre-Louis Bossart 	snd_hdac_stream_spbcap_enable(bus, enable, stream->index);
6292eb4f62SJeeja KP 
6392eb4f62SJeeja KP 	/* set the spib value */
6462582341SPierre-Louis Bossart 	snd_hdac_stream_set_spib(bus, stream, size);
6592eb4f62SJeeja KP 
6692eb4f62SJeeja KP 	return 0;
6792eb4f62SJeeja KP }
6892eb4f62SJeeja KP 
skl_dsp_prepare(struct device * dev,unsigned int format,unsigned int size,struct snd_dma_buffer * dmab)6992eb4f62SJeeja KP static int skl_dsp_prepare(struct device *dev, unsigned int format,
7092eb4f62SJeeja KP 			unsigned int size, struct snd_dma_buffer *dmab)
7192eb4f62SJeeja KP {
7276f56faeSRakesh Ughreja 	struct hdac_bus *bus = dev_get_drvdata(dev);
7392eb4f62SJeeja KP 	struct hdac_ext_stream *estream;
7492eb4f62SJeeja KP 	struct hdac_stream *stream;
7592eb4f62SJeeja KP 	struct snd_pcm_substream substream;
7692eb4f62SJeeja KP 	int ret;
7792eb4f62SJeeja KP 
7892eb4f62SJeeja KP 	if (!bus)
7992eb4f62SJeeja KP 		return -ENODEV;
8092eb4f62SJeeja KP 
8192eb4f62SJeeja KP 	memset(&substream, 0, sizeof(substream));
8292eb4f62SJeeja KP 	substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
8392eb4f62SJeeja KP 
8476f56faeSRakesh Ughreja 	estream = snd_hdac_ext_stream_assign(bus, &substream,
8592eb4f62SJeeja KP 					HDAC_EXT_STREAM_TYPE_HOST);
8692eb4f62SJeeja KP 	if (!estream)
8792eb4f62SJeeja KP 		return -ENODEV;
8892eb4f62SJeeja KP 
8992eb4f62SJeeja KP 	stream = hdac_stream(estream);
9092eb4f62SJeeja KP 
9192eb4f62SJeeja KP 	/* assign decouple host dma channel */
9292eb4f62SJeeja KP 	ret = snd_hdac_dsp_prepare(stream, format, size, dmab);
9392eb4f62SJeeja KP 	if (ret < 0)
9492eb4f62SJeeja KP 		return ret;
9592eb4f62SJeeja KP 
9692eb4f62SJeeja KP 	skl_dsp_setup_spib(dev, size, stream->stream_tag, true);
9792eb4f62SJeeja KP 
9892eb4f62SJeeja KP 	return stream->stream_tag;
9992eb4f62SJeeja KP }
10092eb4f62SJeeja KP 
skl_dsp_trigger(struct device * dev,bool start,int stream_tag)10192eb4f62SJeeja KP static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag)
10292eb4f62SJeeja KP {
10376f56faeSRakesh Ughreja 	struct hdac_bus *bus = dev_get_drvdata(dev);
10492eb4f62SJeeja KP 	struct hdac_stream *stream;
10592eb4f62SJeeja KP 
10692eb4f62SJeeja KP 	if (!bus)
10792eb4f62SJeeja KP 		return -ENODEV;
10892eb4f62SJeeja KP 
10992eb4f62SJeeja KP 	stream = snd_hdac_get_stream(bus,
11092eb4f62SJeeja KP 		SNDRV_PCM_STREAM_PLAYBACK, stream_tag);
11192eb4f62SJeeja KP 	if (!stream)
11292eb4f62SJeeja KP 		return -EINVAL;
11392eb4f62SJeeja KP 
11492eb4f62SJeeja KP 	snd_hdac_dsp_trigger(stream, start);
11592eb4f62SJeeja KP 
11692eb4f62SJeeja KP 	return 0;
11792eb4f62SJeeja KP }
11892eb4f62SJeeja KP 
skl_dsp_cleanup(struct device * dev,struct snd_dma_buffer * dmab,int stream_tag)11992eb4f62SJeeja KP static int skl_dsp_cleanup(struct device *dev,
12092eb4f62SJeeja KP 		struct snd_dma_buffer *dmab, int stream_tag)
12192eb4f62SJeeja KP {
12276f56faeSRakesh Ughreja 	struct hdac_bus *bus = dev_get_drvdata(dev);
12392eb4f62SJeeja KP 	struct hdac_stream *stream;
12492eb4f62SJeeja KP 	struct hdac_ext_stream *estream;
12592eb4f62SJeeja KP 
12692eb4f62SJeeja KP 	if (!bus)
12792eb4f62SJeeja KP 		return -ENODEV;
12892eb4f62SJeeja KP 
12992eb4f62SJeeja KP 	stream = snd_hdac_get_stream(bus,
13092eb4f62SJeeja KP 		SNDRV_PCM_STREAM_PLAYBACK, stream_tag);
13192eb4f62SJeeja KP 	if (!stream)
13292eb4f62SJeeja KP 		return -EINVAL;
13392eb4f62SJeeja KP 
13492eb4f62SJeeja KP 	estream = stream_to_hdac_ext_stream(stream);
13592eb4f62SJeeja KP 	skl_dsp_setup_spib(dev, 0, stream_tag, false);
13692eb4f62SJeeja KP 	snd_hdac_ext_stream_release(estream, HDAC_EXT_STREAM_TYPE_HOST);
13792eb4f62SJeeja KP 
13892eb4f62SJeeja KP 	snd_hdac_dsp_cleanup(stream, dmab);
13992eb4f62SJeeja KP 
14092eb4f62SJeeja KP 	return 0;
14192eb4f62SJeeja KP }
14292eb4f62SJeeja KP 
skl_get_loader_ops(void)143bc23ca35SJeeja KP static struct skl_dsp_loader_ops skl_get_loader_ops(void)
144bc23ca35SJeeja KP {
145bc23ca35SJeeja KP 	struct skl_dsp_loader_ops loader_ops;
146bc23ca35SJeeja KP 
147bc23ca35SJeeja KP 	memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops));
148bc23ca35SJeeja KP 
149bc23ca35SJeeja KP 	loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
150bc23ca35SJeeja KP 	loader_ops.free_dma_buf = skl_free_dma_buf;
151bc23ca35SJeeja KP 
152bc23ca35SJeeja KP 	return loader_ops;
153bc23ca35SJeeja KP };
154bc23ca35SJeeja KP 
bxt_get_loader_ops(void)15592eb4f62SJeeja KP static struct skl_dsp_loader_ops bxt_get_loader_ops(void)
15692eb4f62SJeeja KP {
15792eb4f62SJeeja KP 	struct skl_dsp_loader_ops loader_ops;
15892eb4f62SJeeja KP 
15992eb4f62SJeeja KP 	memset(&loader_ops, 0, sizeof(loader_ops));
16092eb4f62SJeeja KP 
16192eb4f62SJeeja KP 	loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
16292eb4f62SJeeja KP 	loader_ops.free_dma_buf = skl_free_dma_buf;
16392eb4f62SJeeja KP 	loader_ops.prepare = skl_dsp_prepare;
16492eb4f62SJeeja KP 	loader_ops.trigger = skl_dsp_trigger;
16592eb4f62SJeeja KP 	loader_ops.cleanup = skl_dsp_cleanup;
16692eb4f62SJeeja KP 
16792eb4f62SJeeja KP 	return loader_ops;
16892eb4f62SJeeja KP };
16992eb4f62SJeeja KP 
170bc23ca35SJeeja KP static const struct skl_dsp_ops dsp_ops[] = {
171bc23ca35SJeeja KP 	{
172*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_SKL_LP,
173363d4538SDharageswari R 		.num_cores = 2,
174bc23ca35SJeeja KP 		.loader_ops = skl_get_loader_ops,
175bc23ca35SJeeja KP 		.init = skl_sst_dsp_init,
17678cdbbdaSVinod Koul 		.init_fw = skl_sst_init_fw,
177bc23ca35SJeeja KP 		.cleanup = skl_sst_dsp_cleanup
178bc23ca35SJeeja KP 	},
17992eb4f62SJeeja KP 	{
180*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_KBL_LP,
181363d4538SDharageswari R 		.num_cores = 2,
182451dfb5fSVinod Koul 		.loader_ops = skl_get_loader_ops,
183651e4890SPradeep Tewani 		.init = skl_sst_dsp_init,
18478cdbbdaSVinod Koul 		.init_fw = skl_sst_init_fw,
185451dfb5fSVinod Koul 		.cleanup = skl_sst_dsp_cleanup
186451dfb5fSVinod Koul 	},
187451dfb5fSVinod Koul 	{
188*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_APL,
189363d4538SDharageswari R 		.num_cores = 2,
19092eb4f62SJeeja KP 		.loader_ops = bxt_get_loader_ops,
19192eb4f62SJeeja KP 		.init = bxt_sst_dsp_init,
19278cdbbdaSVinod Koul 		.init_fw = bxt_sst_init_fw,
19392eb4f62SJeeja KP 		.cleanup = bxt_sst_dsp_cleanup
19492eb4f62SJeeja KP 	},
19525504863SVinod Koul 	{
196*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_GML,
197363d4538SDharageswari R 		.num_cores = 2,
19825504863SVinod Koul 		.loader_ops = bxt_get_loader_ops,
19925504863SVinod Koul 		.init = bxt_sst_dsp_init,
20025504863SVinod Koul 		.init_fw = bxt_sst_init_fw,
20125504863SVinod Koul 		.cleanup = bxt_sst_dsp_cleanup
20225504863SVinod Koul 	},
203b003a345SGuneshwor Singh 	{
204*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_CNL_LP,
205b003a345SGuneshwor Singh 		.num_cores = 4,
206b003a345SGuneshwor Singh 		.loader_ops = bxt_get_loader_ops,
207b003a345SGuneshwor Singh 		.init = cnl_sst_dsp_init,
208b003a345SGuneshwor Singh 		.init_fw = cnl_sst_init_fw,
209b003a345SGuneshwor Singh 		.cleanup = cnl_sst_dsp_cleanup
210b003a345SGuneshwor Singh 	},
211e6b98db9STakashi Iwai 	{
212*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_CNL_H,
213e6b98db9STakashi Iwai 		.num_cores = 4,
214e6b98db9STakashi Iwai 		.loader_ops = bxt_get_loader_ops,
215e6b98db9STakashi Iwai 		.init = cnl_sst_dsp_init,
216e6b98db9STakashi Iwai 		.init_fw = cnl_sst_init_fw,
217e6b98db9STakashi Iwai 		.cleanup = cnl_sst_dsp_cleanup
218e6b98db9STakashi Iwai 	},
2195f740b24SEvan Green 	{
220*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_CML_LP,
2215f740b24SEvan Green 		.num_cores = 4,
2225f740b24SEvan Green 		.loader_ops = bxt_get_loader_ops,
2235f740b24SEvan Green 		.init = cnl_sst_dsp_init,
2245f740b24SEvan Green 		.init_fw = cnl_sst_init_fw,
2255f740b24SEvan Green 		.cleanup = cnl_sst_dsp_cleanup
2265f740b24SEvan Green 	},
2275f740b24SEvan Green 	{
228*a2db8743SAmadeusz Sławiński 		.id = PCI_DEVICE_ID_INTEL_HDA_CML_H,
2295f740b24SEvan Green 		.num_cores = 4,
2305f740b24SEvan Green 		.loader_ops = bxt_get_loader_ops,
2315f740b24SEvan Green 		.init = cnl_sst_dsp_init,
2325f740b24SEvan Green 		.init_fw = cnl_sst_init_fw,
2335f740b24SEvan Green 		.cleanup = cnl_sst_dsp_cleanup
2345f740b24SEvan Green 	},
235bc23ca35SJeeja KP };
236bc23ca35SJeeja KP 
skl_get_dsp_ops(int pci_id)23773a67581SVinod Koul const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id)
238bc23ca35SJeeja KP {
239bc23ca35SJeeja KP 	int i;
240bc23ca35SJeeja KP 
241bc23ca35SJeeja KP 	for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
242bc23ca35SJeeja KP 		if (dsp_ops[i].id == pci_id)
24373a67581SVinod Koul 			return &dsp_ops[i];
244bc23ca35SJeeja KP 	}
245bc23ca35SJeeja KP 
24673a67581SVinod Koul 	return NULL;
247bc23ca35SJeeja KP }
248bc23ca35SJeeja KP 
skl_init_dsp(struct skl_dev * skl)249bcc2a2dcSCezary Rojewski int skl_init_dsp(struct skl_dev *skl)
250d255b095SJeeja KP {
251d255b095SJeeja KP 	void __iomem *mmio_base;
25276f56faeSRakesh Ughreja 	struct hdac_bus *bus = skl_to_bus(skl);
253d255b095SJeeja KP 	struct skl_dsp_loader_ops loader_ops;
254bc23ca35SJeeja KP 	int irq = bus->irq;
25573a67581SVinod Koul 	const struct skl_dsp_ops *ops;
256f0a550a8SGuneshwor Singh 	struct skl_dsp_cores *cores;
25773a67581SVinod Koul 	int ret;
258d255b095SJeeja KP 
259d255b095SJeeja KP 	/* enable ppcap interrupt */
26076f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_enable(bus, true);
26176f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_int_enable(bus, true);
262d255b095SJeeja KP 
263d255b095SJeeja KP 	/* read the BAR of the ADSP MMIO */
264d255b095SJeeja KP 	mmio_base = pci_ioremap_bar(skl->pci, 4);
265d255b095SJeeja KP 	if (mmio_base == NULL) {
266d255b095SJeeja KP 		dev_err(bus->dev, "ioremap error\n");
267d255b095SJeeja KP 		return -ENXIO;
268d255b095SJeeja KP 	}
269d255b095SJeeja KP 
27073a67581SVinod Koul 	ops = skl_get_dsp_ops(skl->pci->device);
271f77d443cSSubhransu S. Prusty 	if (!ops) {
272f77d443cSSubhransu S. Prusty 		ret = -EIO;
2739149916fSSubhransu S. Prusty 		goto unmap_mmio;
274f77d443cSSubhransu S. Prusty 	}
275bc23ca35SJeeja KP 
27673a67581SVinod Koul 	loader_ops = ops->loader_ops();
27773a67581SVinod Koul 	ret = ops->init(bus->dev, mmio_base, irq,
27873a67581SVinod Koul 				skl->fw_name, loader_ops,
279bcc2a2dcSCezary Rojewski 				&skl);
280bc23ca35SJeeja KP 
2812ac454ffSJeeja KP 	if (ret < 0)
282f77d443cSSubhransu S. Prusty 		goto unmap_mmio;
2832ac454ffSJeeja KP 
284bcc2a2dcSCezary Rojewski 	skl->dsp_ops = ops;
285bcc2a2dcSCezary Rojewski 	cores = &skl->cores;
286f0a550a8SGuneshwor Singh 	cores->count = ops->num_cores;
287f0a550a8SGuneshwor Singh 
288f0a550a8SGuneshwor Singh 	cores->state = kcalloc(cores->count, sizeof(*cores->state), GFP_KERNEL);
289f77d443cSSubhransu S. Prusty 	if (!cores->state) {
290f77d443cSSubhransu S. Prusty 		ret = -ENOMEM;
291f77d443cSSubhransu S. Prusty 		goto unmap_mmio;
292f77d443cSSubhransu S. Prusty 	}
293f0a550a8SGuneshwor Singh 
294f0a550a8SGuneshwor Singh 	cores->usage_count = kcalloc(cores->count, sizeof(*cores->usage_count),
295f0a550a8SGuneshwor Singh 				     GFP_KERNEL);
296f0a550a8SGuneshwor Singh 	if (!cores->usage_count) {
297f77d443cSSubhransu S. Prusty 		ret = -ENOMEM;
298f77d443cSSubhransu S. Prusty 		goto free_core_state;
299f0a550a8SGuneshwor Singh 	}
300363d4538SDharageswari R 
301d255b095SJeeja KP 	dev_dbg(bus->dev, "dsp registration status=%d\n", ret);
302d255b095SJeeja KP 
303f77d443cSSubhransu S. Prusty 	return 0;
304f77d443cSSubhransu S. Prusty 
305f77d443cSSubhransu S. Prusty free_core_state:
306f77d443cSSubhransu S. Prusty 	kfree(cores->state);
307f77d443cSSubhransu S. Prusty 
308f77d443cSSubhransu S. Prusty unmap_mmio:
309f77d443cSSubhransu S. Prusty 	iounmap(mmio_base);
310f77d443cSSubhransu S. Prusty 
311d255b095SJeeja KP 	return ret;
312d255b095SJeeja KP }
313d255b095SJeeja KP 
skl_free_dsp(struct skl_dev * skl)314bcc2a2dcSCezary Rojewski int skl_free_dsp(struct skl_dev *skl)
315d255b095SJeeja KP {
31676f56faeSRakesh Ughreja 	struct hdac_bus *bus = skl_to_bus(skl);
317d255b095SJeeja KP 
318d255b095SJeeja KP 	/* disable  ppcap interrupt */
31976f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_int_enable(bus, false);
320d255b095SJeeja KP 
321bcc2a2dcSCezary Rojewski 	skl->dsp_ops->cleanup(bus->dev, skl);
322bc23ca35SJeeja KP 
323bcc2a2dcSCezary Rojewski 	kfree(skl->cores.state);
324bcc2a2dcSCezary Rojewski 	kfree(skl->cores.usage_count);
325f0a550a8SGuneshwor Singh 
326bcc2a2dcSCezary Rojewski 	if (skl->dsp->addr.lpe)
327bcc2a2dcSCezary Rojewski 		iounmap(skl->dsp->addr.lpe);
328bc23ca35SJeeja KP 
329bc23ca35SJeeja KP 	return 0;
330d255b095SJeeja KP }
331d255b095SJeeja KP 
3328b4a133cSJayachandran B /*
3338b4a133cSJayachandran B  * In the case of "suspend_active" i.e, the Audio IP being active
3348b4a133cSJayachandran B  * during system suspend, immediately excecute any pending D0i3 work
3358b4a133cSJayachandran B  * before suspending. This is needed for the IP to work in low power
3368b4a133cSJayachandran B  * mode during system suspend. In the case of normal suspend, cancel
3378b4a133cSJayachandran B  * any pending D0i3 work.
3388b4a133cSJayachandran B  */
skl_suspend_late_dsp(struct skl_dev * skl)339bcc2a2dcSCezary Rojewski int skl_suspend_late_dsp(struct skl_dev *skl)
3408b4a133cSJayachandran B {
3418b4a133cSJayachandran B 	struct delayed_work *dwork;
3428b4a133cSJayachandran B 
343bcc2a2dcSCezary Rojewski 	if (!skl)
3448b4a133cSJayachandran B 		return 0;
3458b4a133cSJayachandran B 
346bcc2a2dcSCezary Rojewski 	dwork = &skl->d0i3.work;
3478b4a133cSJayachandran B 
3488b4a133cSJayachandran B 	if (dwork->work.func) {
3498b4a133cSJayachandran B 		if (skl->supend_active)
3508b4a133cSJayachandran B 			flush_delayed_work(dwork);
3518b4a133cSJayachandran B 		else
3528b4a133cSJayachandran B 			cancel_delayed_work_sync(dwork);
3538b4a133cSJayachandran B 	}
3548b4a133cSJayachandran B 
3558b4a133cSJayachandran B 	return 0;
3568b4a133cSJayachandran B }
3578b4a133cSJayachandran B 
skl_suspend_dsp(struct skl_dev * skl)358bcc2a2dcSCezary Rojewski int skl_suspend_dsp(struct skl_dev *skl)
359d255b095SJeeja KP {
36076f56faeSRakesh Ughreja 	struct hdac_bus *bus = skl_to_bus(skl);
361d255b095SJeeja KP 	int ret;
362d255b095SJeeja KP 
363d255b095SJeeja KP 	/* if ppcap is not supported return 0 */
36476f56faeSRakesh Ughreja 	if (!bus->ppcap)
365d255b095SJeeja KP 		return 0;
366d255b095SJeeja KP 
367bcc2a2dcSCezary Rojewski 	ret = skl_dsp_sleep(skl->dsp);
368d255b095SJeeja KP 	if (ret < 0)
369d255b095SJeeja KP 		return ret;
370d255b095SJeeja KP 
371d255b095SJeeja KP 	/* disable ppcap interrupt */
37276f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_int_enable(bus, false);
37376f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_enable(bus, false);
374d255b095SJeeja KP 
375d255b095SJeeja KP 	return 0;
376d255b095SJeeja KP }
377d255b095SJeeja KP 
skl_resume_dsp(struct skl_dev * skl)378bcc2a2dcSCezary Rojewski int skl_resume_dsp(struct skl_dev *skl)
379d255b095SJeeja KP {
38076f56faeSRakesh Ughreja 	struct hdac_bus *bus = skl_to_bus(skl);
3814e10996bSJeeja KP 	int ret;
382d255b095SJeeja KP 
383d255b095SJeeja KP 	/* if ppcap is not supported return 0 */
38476f56faeSRakesh Ughreja 	if (!bus->ppcap)
385d255b095SJeeja KP 		return 0;
386d255b095SJeeja KP 
387d255b095SJeeja KP 	/* enable ppcap interrupt */
38876f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_enable(bus, true);
38976f56faeSRakesh Ughreja 	snd_hdac_ext_bus_ppcap_int_enable(bus, true);
390d255b095SJeeja KP 
39178cdbbdaSVinod Koul 	/* check if DSP 1st boot is done */
392bcc2a2dcSCezary Rojewski 	if (skl->is_first_boot)
39378cdbbdaSVinod Koul 		return 0;
39478cdbbdaSVinod Koul 
395fc9fdd61SSanyog Kale 	/*
396fc9fdd61SSanyog Kale 	 * Disable dynamic clock and power gating during firmware
397fc9fdd61SSanyog Kale 	 * and library download
398fc9fdd61SSanyog Kale 	 */
399bcc2a2dcSCezary Rojewski 	skl->enable_miscbdcge(skl->dev, false);
400bcc2a2dcSCezary Rojewski 	skl->clock_power_gating(skl->dev, false);
401d5cc0a1fSPardha Saradhi K 
402bcc2a2dcSCezary Rojewski 	ret = skl_dsp_wake(skl->dsp);
403bcc2a2dcSCezary Rojewski 	skl->enable_miscbdcge(skl->dev, true);
404bcc2a2dcSCezary Rojewski 	skl->clock_power_gating(skl->dev, true);
4054e10996bSJeeja KP 	if (ret < 0)
4064e10996bSJeeja KP 		return ret;
4074e10996bSJeeja KP 
4089452314dSPradeep Tewani 	if (skl->cfg.astate_cfg != NULL) {
409bcc2a2dcSCezary Rojewski 		skl_dsp_set_astate_cfg(skl, skl->cfg.astate_cfg->count,
4109452314dSPradeep Tewani 					skl->cfg.astate_cfg);
4119452314dSPradeep Tewani 	}
4124e10996bSJeeja KP 	return ret;
413d255b095SJeeja KP }
41423db472bSJeeja KP 
skl_get_bit_depth(int params)41523db472bSJeeja KP enum skl_bitdepth skl_get_bit_depth(int params)
41623db472bSJeeja KP {
41723db472bSJeeja KP 	switch (params) {
41823db472bSJeeja KP 	case 8:
41923db472bSJeeja KP 		return SKL_DEPTH_8BIT;
42023db472bSJeeja KP 
42123db472bSJeeja KP 	case 16:
42223db472bSJeeja KP 		return SKL_DEPTH_16BIT;
42323db472bSJeeja KP 
42423db472bSJeeja KP 	case 24:
42523db472bSJeeja KP 		return SKL_DEPTH_24BIT;
42623db472bSJeeja KP 
42723db472bSJeeja KP 	case 32:
42823db472bSJeeja KP 		return SKL_DEPTH_32BIT;
42923db472bSJeeja KP 
43023db472bSJeeja KP 	default:
43123db472bSJeeja KP 		return SKL_DEPTH_INVALID;
43223db472bSJeeja KP 
43323db472bSJeeja KP 	}
43423db472bSJeeja KP }
43523db472bSJeeja KP 
43623db472bSJeeja KP /*
43723db472bSJeeja KP  * Each module in DSP expects a base module configuration, which consists of
43823db472bSJeeja KP  * PCM format information, which we calculate in driver and resource values
43923db472bSJeeja KP  * which are read from widget information passed through topology binary
44023db472bSJeeja KP  * This is send when we create a module with INIT_INSTANCE IPC msg
44123db472bSJeeja KP  */
skl_set_base_module_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_base_cfg * base_cfg)442bcc2a2dcSCezary Rojewski static void skl_set_base_module_format(struct skl_dev *skl,
44323db472bSJeeja KP 			struct skl_module_cfg *mconfig,
44423db472bSJeeja KP 			struct skl_base_cfg *base_cfg)
44523db472bSJeeja KP {
446f6fa56e2SRamesh Babu 	struct skl_module *module = mconfig->module;
447f6fa56e2SRamesh Babu 	struct skl_module_res *res = &module->resources[mconfig->res_idx];
448f6fa56e2SRamesh Babu 	struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
449f6fa56e2SRamesh Babu 	struct skl_module_fmt *format = &fmt->inputs[0].fmt;
45023db472bSJeeja KP 
451f6fa56e2SRamesh Babu 	base_cfg->audio_fmt.number_of_channels = format->channels;
45223db472bSJeeja KP 
45323db472bSJeeja KP 	base_cfg->audio_fmt.s_freq = format->s_freq;
45423db472bSJeeja KP 	base_cfg->audio_fmt.bit_depth = format->bit_depth;
45523db472bSJeeja KP 	base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth;
45623db472bSJeeja KP 	base_cfg->audio_fmt.ch_cfg = format->ch_cfg;
45736e075ceSJenny TC 	base_cfg->audio_fmt.sample_type = format->sample_type;
45823db472bSJeeja KP 
459bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n",
46023db472bSJeeja KP 			format->bit_depth, format->valid_bit_depth,
46123db472bSJeeja KP 			format->ch_cfg);
46223db472bSJeeja KP 
4633e81f1a3SJeeja KP 	base_cfg->audio_fmt.channel_map = format->ch_map;
46423db472bSJeeja KP 
4653e81f1a3SJeeja KP 	base_cfg->audio_fmt.interleaving = format->interleaving_style;
46623db472bSJeeja KP 
46784b71067SCezary Rojewski 	base_cfg->cpc = res->cpc;
468f6fa56e2SRamesh Babu 	base_cfg->ibs = res->ibs;
469f6fa56e2SRamesh Babu 	base_cfg->obs = res->obs;
470f6fa56e2SRamesh Babu 	base_cfg->is_pages = res->is_pages;
47123db472bSJeeja KP }
47223db472bSJeeja KP 
fill_pin_params(struct skl_audio_data_format * pin_fmt,struct skl_module_fmt * format)473db5a3f83SSzymon Mielczarek static void fill_pin_params(struct skl_audio_data_format *pin_fmt,
474db5a3f83SSzymon Mielczarek 			    struct skl_module_fmt *format)
475db5a3f83SSzymon Mielczarek {
476db5a3f83SSzymon Mielczarek 	pin_fmt->number_of_channels = format->channels;
477db5a3f83SSzymon Mielczarek 	pin_fmt->s_freq = format->s_freq;
478db5a3f83SSzymon Mielczarek 	pin_fmt->bit_depth = format->bit_depth;
479db5a3f83SSzymon Mielczarek 	pin_fmt->valid_bit_depth = format->valid_bit_depth;
480db5a3f83SSzymon Mielczarek 	pin_fmt->ch_cfg = format->ch_cfg;
481db5a3f83SSzymon Mielczarek 	pin_fmt->sample_type = format->sample_type;
482db5a3f83SSzymon Mielczarek 	pin_fmt->channel_map = format->ch_map;
483db5a3f83SSzymon Mielczarek 	pin_fmt->interleaving = format->interleaving_style;
484db5a3f83SSzymon Mielczarek }
485db5a3f83SSzymon Mielczarek 
486db5a3f83SSzymon Mielczarek /*
487db5a3f83SSzymon Mielczarek  * Any module configuration begins with a base module configuration but
488db5a3f83SSzymon Mielczarek  * can be followed by a generic extension containing audio format for all
489db5a3f83SSzymon Mielczarek  * module's pins that are in use.
490db5a3f83SSzymon Mielczarek  */
skl_set_base_ext_module_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_base_cfg_ext * base_cfg_ext)491db5a3f83SSzymon Mielczarek static void skl_set_base_ext_module_format(struct skl_dev *skl,
492db5a3f83SSzymon Mielczarek 					   struct skl_module_cfg *mconfig,
493db5a3f83SSzymon Mielczarek 					   struct skl_base_cfg_ext *base_cfg_ext)
494db5a3f83SSzymon Mielczarek {
495db5a3f83SSzymon Mielczarek 	struct skl_module *module = mconfig->module;
496db5a3f83SSzymon Mielczarek 	struct skl_module_pin_resources *pin_res;
497db5a3f83SSzymon Mielczarek 	struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
498db5a3f83SSzymon Mielczarek 	struct skl_module_res *res = &module->resources[mconfig->res_idx];
499db5a3f83SSzymon Mielczarek 	struct skl_module_fmt *format;
500db5a3f83SSzymon Mielczarek 	struct skl_pin_format *pin_fmt;
501db5a3f83SSzymon Mielczarek 	char *params;
502db5a3f83SSzymon Mielczarek 	int i;
503db5a3f83SSzymon Mielczarek 
504db5a3f83SSzymon Mielczarek 	base_cfg_ext->nr_input_pins = res->nr_input_pins;
505db5a3f83SSzymon Mielczarek 	base_cfg_ext->nr_output_pins = res->nr_output_pins;
506db5a3f83SSzymon Mielczarek 	base_cfg_ext->priv_param_length =
507db5a3f83SSzymon Mielczarek 		mconfig->formats_config[SKL_PARAM_INIT].caps_size;
508db5a3f83SSzymon Mielczarek 
509db5a3f83SSzymon Mielczarek 	for (i = 0; i < res->nr_input_pins; i++) {
510db5a3f83SSzymon Mielczarek 		pin_res = &res->input[i];
511db5a3f83SSzymon Mielczarek 		pin_fmt = &base_cfg_ext->pins_fmt[i];
512db5a3f83SSzymon Mielczarek 
513db5a3f83SSzymon Mielczarek 		pin_fmt->pin_idx = pin_res->pin_index;
514db5a3f83SSzymon Mielczarek 		pin_fmt->buf_size = pin_res->buf_size;
515db5a3f83SSzymon Mielczarek 
516db5a3f83SSzymon Mielczarek 		format = &fmt->inputs[pin_res->pin_index].fmt;
517db5a3f83SSzymon Mielczarek 		fill_pin_params(&pin_fmt->audio_fmt, format);
518db5a3f83SSzymon Mielczarek 	}
519db5a3f83SSzymon Mielczarek 
520db5a3f83SSzymon Mielczarek 	for (i = 0; i < res->nr_output_pins; i++) {
521db5a3f83SSzymon Mielczarek 		pin_res = &res->output[i];
522db5a3f83SSzymon Mielczarek 		pin_fmt = &base_cfg_ext->pins_fmt[res->nr_input_pins + i];
523db5a3f83SSzymon Mielczarek 
524db5a3f83SSzymon Mielczarek 		pin_fmt->pin_idx = pin_res->pin_index;
525db5a3f83SSzymon Mielczarek 		pin_fmt->buf_size = pin_res->buf_size;
526db5a3f83SSzymon Mielczarek 
527db5a3f83SSzymon Mielczarek 		format = &fmt->outputs[pin_res->pin_index].fmt;
528db5a3f83SSzymon Mielczarek 		fill_pin_params(&pin_fmt->audio_fmt, format);
529db5a3f83SSzymon Mielczarek 	}
530db5a3f83SSzymon Mielczarek 
531db5a3f83SSzymon Mielczarek 	if (!base_cfg_ext->priv_param_length)
532db5a3f83SSzymon Mielczarek 		return;
533db5a3f83SSzymon Mielczarek 
534db5a3f83SSzymon Mielczarek 	params = (char *)base_cfg_ext + sizeof(struct skl_base_cfg_ext);
535db5a3f83SSzymon Mielczarek 	params += (base_cfg_ext->nr_input_pins + base_cfg_ext->nr_output_pins) *
536db5a3f83SSzymon Mielczarek 		  sizeof(struct skl_pin_format);
537db5a3f83SSzymon Mielczarek 
538db5a3f83SSzymon Mielczarek 	memcpy(params, mconfig->formats_config[SKL_PARAM_INIT].caps,
539db5a3f83SSzymon Mielczarek 	       mconfig->formats_config[SKL_PARAM_INIT].caps_size);
540db5a3f83SSzymon Mielczarek }
541db5a3f83SSzymon Mielczarek 
54223db472bSJeeja KP /*
54323db472bSJeeja KP  * Copies copier capabilities into copier module and updates copier module
54423db472bSJeeja KP  * config size.
54523db472bSJeeja KP  */
skl_copy_copier_caps(struct skl_module_cfg * mconfig,struct skl_cpr_cfg * cpr_mconfig)54623db472bSJeeja KP static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
54723db472bSJeeja KP 				struct skl_cpr_cfg *cpr_mconfig)
54823db472bSJeeja KP {
549a4ad42d2SKareem Shaik 	if (mconfig->formats_config[SKL_PARAM_INIT].caps_size == 0)
55023db472bSJeeja KP 		return;
55123db472bSJeeja KP 
5521fd61d01SAmadeusz Sławiński 	memcpy(&cpr_mconfig->gtw_cfg.config_data,
553a4ad42d2SKareem Shaik 			mconfig->formats_config[SKL_PARAM_INIT].caps,
554a4ad42d2SKareem Shaik 			mconfig->formats_config[SKL_PARAM_INIT].caps_size);
55523db472bSJeeja KP 
55623db472bSJeeja KP 	cpr_mconfig->gtw_cfg.config_length =
557a4ad42d2SKareem Shaik 			(mconfig->formats_config[SKL_PARAM_INIT].caps_size) / 4;
55823db472bSJeeja KP }
55923db472bSJeeja KP 
560bfa764acSJeeja KP #define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF
56123db472bSJeeja KP /*
56223db472bSJeeja KP  * Calculate the gatewat settings required for copier module, type of
56323db472bSJeeja KP  * gateway and index of gateway to use
56423db472bSJeeja KP  */
skl_get_node_id(struct skl_dev * skl,struct skl_module_cfg * mconfig)565bcc2a2dcSCezary Rojewski static u32 skl_get_node_id(struct skl_dev *skl,
5664fdf810fSDharageswari.R 			struct skl_module_cfg *mconfig)
56723db472bSJeeja KP {
56823db472bSJeeja KP 	union skl_connector_node_id node_id = {0};
569d7b18813SJeeja KP 	union skl_ssp_dma_node ssp_node  = {0};
57023db472bSJeeja KP 	struct skl_pipe_params *params = mconfig->pipe->p_params;
57123db472bSJeeja KP 
57223db472bSJeeja KP 	switch (mconfig->dev_type) {
57323db472bSJeeja KP 	case SKL_DEVICE_BT:
57423db472bSJeeja KP 		node_id.node.dma_type =
57523db472bSJeeja KP 			(SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
57623db472bSJeeja KP 			SKL_DMA_I2S_LINK_OUTPUT_CLASS :
57723db472bSJeeja KP 			SKL_DMA_I2S_LINK_INPUT_CLASS;
57823db472bSJeeja KP 		node_id.node.vindex = params->host_dma_id +
57923db472bSJeeja KP 					(mconfig->vbus_id << 3);
58023db472bSJeeja KP 		break;
58123db472bSJeeja KP 
58223db472bSJeeja KP 	case SKL_DEVICE_I2S:
58323db472bSJeeja KP 		node_id.node.dma_type =
58423db472bSJeeja KP 			(SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
58523db472bSJeeja KP 			SKL_DMA_I2S_LINK_OUTPUT_CLASS :
58623db472bSJeeja KP 			SKL_DMA_I2S_LINK_INPUT_CLASS;
587d7b18813SJeeja KP 		ssp_node.dma_node.time_slot_index = mconfig->time_slot;
588d7b18813SJeeja KP 		ssp_node.dma_node.i2s_instance = mconfig->vbus_id;
589d7b18813SJeeja KP 		node_id.node.vindex = ssp_node.val;
59023db472bSJeeja KP 		break;
59123db472bSJeeja KP 
59223db472bSJeeja KP 	case SKL_DEVICE_DMIC:
59323db472bSJeeja KP 		node_id.node.dma_type = SKL_DMA_DMIC_LINK_INPUT_CLASS;
59423db472bSJeeja KP 		node_id.node.vindex = mconfig->vbus_id +
59523db472bSJeeja KP 					 (mconfig->time_slot);
59623db472bSJeeja KP 		break;
59723db472bSJeeja KP 
59823db472bSJeeja KP 	case SKL_DEVICE_HDALINK:
59923db472bSJeeja KP 		node_id.node.dma_type =
60023db472bSJeeja KP 			(SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
60123db472bSJeeja KP 			SKL_DMA_HDA_LINK_OUTPUT_CLASS :
60223db472bSJeeja KP 			SKL_DMA_HDA_LINK_INPUT_CLASS;
60323db472bSJeeja KP 		node_id.node.vindex = params->link_dma_id;
60423db472bSJeeja KP 		break;
60523db472bSJeeja KP 
606bfa764acSJeeja KP 	case SKL_DEVICE_HDAHOST:
60723db472bSJeeja KP 		node_id.node.dma_type =
60823db472bSJeeja KP 			(SKL_CONN_SOURCE == mconfig->hw_conn_type) ?
60923db472bSJeeja KP 			SKL_DMA_HDA_HOST_OUTPUT_CLASS :
61023db472bSJeeja KP 			SKL_DMA_HDA_HOST_INPUT_CLASS;
61123db472bSJeeja KP 		node_id.node.vindex = params->host_dma_id;
61223db472bSJeeja KP 		break;
613bfa764acSJeeja KP 
614bfa764acSJeeja KP 	default:
6154fdf810fSDharageswari.R 		node_id.val = 0xFFFFFFFF;
6164fdf810fSDharageswari.R 		break;
6174fdf810fSDharageswari.R 	}
6184fdf810fSDharageswari.R 
6194fdf810fSDharageswari.R 	return node_id.val;
6204fdf810fSDharageswari.R }
6214fdf810fSDharageswari.R 
skl_setup_cpr_gateway_cfg(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_cpr_cfg * cpr_mconfig)622bcc2a2dcSCezary Rojewski static void skl_setup_cpr_gateway_cfg(struct skl_dev *skl,
6234fdf810fSDharageswari.R 			struct skl_module_cfg *mconfig,
6244fdf810fSDharageswari.R 			struct skl_cpr_cfg *cpr_mconfig)
6254fdf810fSDharageswari.R {
626f6e6ab1dSRamesh Babu 	u32 dma_io_buf;
627f6fa56e2SRamesh Babu 	struct skl_module_res *res;
628f6fa56e2SRamesh Babu 	int res_idx = mconfig->res_idx;
629f6e6ab1dSRamesh Babu 
630bcc2a2dcSCezary Rojewski 	cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(skl, mconfig);
6314fdf810fSDharageswari.R 
6324fdf810fSDharageswari.R 	if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
633bfa764acSJeeja KP 		cpr_mconfig->cpr_feature_mask = 0;
634bfa764acSJeeja KP 		return;
63523db472bSJeeja KP 	}
63623db472bSJeeja KP 
637f6fa56e2SRamesh Babu 	if (skl->nr_modules) {
638f6fa56e2SRamesh Babu 		res = &mconfig->module->resources[mconfig->res_idx];
639f6fa56e2SRamesh Babu 		cpr_mconfig->gtw_cfg.dma_buffer_size = res->dma_buffer_size;
640f6fa56e2SRamesh Babu 		goto skip_buf_size_calc;
641f6fa56e2SRamesh Babu 	} else {
642f6fa56e2SRamesh Babu 		res = &mconfig->module->resources[res_idx];
643f6fa56e2SRamesh Babu 	}
644f6fa56e2SRamesh Babu 
645f6e6ab1dSRamesh Babu 	switch (mconfig->hw_conn_type) {
646f6e6ab1dSRamesh Babu 	case SKL_CONN_SOURCE:
647f6e6ab1dSRamesh Babu 		if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
648f6fa56e2SRamesh Babu 			dma_io_buf =  res->ibs;
64923db472bSJeeja KP 		else
650f6fa56e2SRamesh Babu 			dma_io_buf =  res->obs;
651f6e6ab1dSRamesh Babu 		break;
652f6e6ab1dSRamesh Babu 
653f6e6ab1dSRamesh Babu 	case SKL_CONN_SINK:
654f6e6ab1dSRamesh Babu 		if (mconfig->dev_type == SKL_DEVICE_HDAHOST)
655f6fa56e2SRamesh Babu 			dma_io_buf =  res->obs;
656f6e6ab1dSRamesh Babu 		else
657f6fa56e2SRamesh Babu 			dma_io_buf =  res->ibs;
658f6e6ab1dSRamesh Babu 		break;
659f6e6ab1dSRamesh Babu 
660f6e6ab1dSRamesh Babu 	default:
661bcc2a2dcSCezary Rojewski 		dev_warn(skl->dev, "wrong connection type: %d\n",
662f6e6ab1dSRamesh Babu 				mconfig->hw_conn_type);
663f6e6ab1dSRamesh Babu 		return;
664f6e6ab1dSRamesh Babu 	}
665f6e6ab1dSRamesh Babu 
666f6e6ab1dSRamesh Babu 	cpr_mconfig->gtw_cfg.dma_buffer_size =
667f6e6ab1dSRamesh Babu 				mconfig->dma_buffer_size * dma_io_buf;
66823db472bSJeeja KP 
6695b43af6dSSubhransu S. Prusty 	/* fallback to 2ms default value */
6705b43af6dSSubhransu S. Prusty 	if (!cpr_mconfig->gtw_cfg.dma_buffer_size) {
6715b43af6dSSubhransu S. Prusty 		if (mconfig->hw_conn_type == SKL_CONN_SOURCE)
672f6fa56e2SRamesh Babu 			cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->obs;
6735b43af6dSSubhransu S. Prusty 		else
674f6fa56e2SRamesh Babu 			cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * res->ibs;
6755b43af6dSSubhransu S. Prusty 	}
6765b43af6dSSubhransu S. Prusty 
677f6fa56e2SRamesh Babu skip_buf_size_calc:
67823db472bSJeeja KP 	cpr_mconfig->cpr_feature_mask = 0;
67923db472bSJeeja KP 	cpr_mconfig->gtw_cfg.config_length  = 0;
68023db472bSJeeja KP 
68123db472bSJeeja KP 	skl_copy_copier_caps(mconfig, cpr_mconfig);
68223db472bSJeeja KP }
68323db472bSJeeja KP 
684c115fa5eSDharageswari.R #define DMA_CONTROL_ID 5
6855514830dSJaikrishna Nemallapudi #define DMA_I2S_BLOB_SIZE 21
686c115fa5eSDharageswari.R 
skl_dsp_set_dma_control(struct skl_dev * skl,u32 * caps,u32 caps_size,u32 node_id)687bcc2a2dcSCezary Rojewski int skl_dsp_set_dma_control(struct skl_dev *skl, u32 *caps,
6885514830dSJaikrishna Nemallapudi 				u32 caps_size, u32 node_id)
689c115fa5eSDharageswari.R {
690c115fa5eSDharageswari.R 	struct skl_dma_control *dma_ctrl;
691c115fa5eSDharageswari.R 	struct skl_ipc_large_config_msg msg = {0};
692c115fa5eSDharageswari.R 	int err = 0;
693c115fa5eSDharageswari.R 
694c115fa5eSDharageswari.R 
695c115fa5eSDharageswari.R 	/*
696c186fe74SGuruprasadX Pawse 	 * if blob size zero, then return
697c115fa5eSDharageswari.R 	 */
6985514830dSJaikrishna Nemallapudi 	if (caps_size == 0)
699c115fa5eSDharageswari.R 		return 0;
700c115fa5eSDharageswari.R 
701c115fa5eSDharageswari.R 	msg.large_param_id = DMA_CONTROL_ID;
7025514830dSJaikrishna Nemallapudi 	msg.param_data_size = sizeof(struct skl_dma_control) + caps_size;
703c115fa5eSDharageswari.R 
704c115fa5eSDharageswari.R 	dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
705c115fa5eSDharageswari.R 	if (dma_ctrl == NULL)
706c115fa5eSDharageswari.R 		return -ENOMEM;
707c115fa5eSDharageswari.R 
7085514830dSJaikrishna Nemallapudi 	dma_ctrl->node_id = node_id;
709c115fa5eSDharageswari.R 
7105514830dSJaikrishna Nemallapudi 	/*
7115514830dSJaikrishna Nemallapudi 	 * NHLT blob may contain additional configs along with i2s blob.
7125514830dSJaikrishna Nemallapudi 	 * firmware expects only the i2s blob size as the config_length.
7135514830dSJaikrishna Nemallapudi 	 * So fix to i2s blob size.
7145514830dSJaikrishna Nemallapudi 	 * size in dwords.
7155514830dSJaikrishna Nemallapudi 	 */
7165514830dSJaikrishna Nemallapudi 	dma_ctrl->config_length = DMA_I2S_BLOB_SIZE;
717c115fa5eSDharageswari.R 
7185514830dSJaikrishna Nemallapudi 	memcpy(dma_ctrl->config_data, caps, caps_size);
719c115fa5eSDharageswari.R 
720bcc2a2dcSCezary Rojewski 	err = skl_ipc_set_large_config(&skl->ipc, &msg, (u32 *)dma_ctrl);
721c115fa5eSDharageswari.R 
722c115fa5eSDharageswari.R 	kfree(dma_ctrl);
723c115fa5eSDharageswari.R 	return err;
724c115fa5eSDharageswari.R }
72501f50d69SSriram Periyasamy EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control);
726c115fa5eSDharageswari.R 
skl_setup_out_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_audio_data_format * out_fmt)727bcc2a2dcSCezary Rojewski static void skl_setup_out_format(struct skl_dev *skl,
72823db472bSJeeja KP 			struct skl_module_cfg *mconfig,
72923db472bSJeeja KP 			struct skl_audio_data_format *out_fmt)
73023db472bSJeeja KP {
731f6fa56e2SRamesh Babu 	struct skl_module *module = mconfig->module;
732f6fa56e2SRamesh Babu 	struct skl_module_iface *fmt = &module->formats[mconfig->fmt_idx];
733f6fa56e2SRamesh Babu 	struct skl_module_fmt *format = &fmt->outputs[0].fmt;
73423db472bSJeeja KP 
73523db472bSJeeja KP 	out_fmt->number_of_channels = (u8)format->channels;
73623db472bSJeeja KP 	out_fmt->s_freq = format->s_freq;
73723db472bSJeeja KP 	out_fmt->bit_depth = format->bit_depth;
73823db472bSJeeja KP 	out_fmt->valid_bit_depth = format->valid_bit_depth;
73923db472bSJeeja KP 	out_fmt->ch_cfg = format->ch_cfg;
74023db472bSJeeja KP 
7413e81f1a3SJeeja KP 	out_fmt->channel_map = format->ch_map;
7423e81f1a3SJeeja KP 	out_fmt->interleaving = format->interleaving_style;
7433e81f1a3SJeeja KP 	out_fmt->sample_type = format->sample_type;
74423db472bSJeeja KP 
745bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "copier out format chan=%d fre=%d bitdepth=%d\n",
74623db472bSJeeja KP 		out_fmt->number_of_channels, format->s_freq, format->bit_depth);
74723db472bSJeeja KP }
74823db472bSJeeja KP 
74923db472bSJeeja KP /*
750a0ffe48bSHardik T Shah  * DSP needs SRC module for frequency conversion, SRC takes base module
751a0ffe48bSHardik T Shah  * configuration and the target frequency as extra parameter passed as src
752a0ffe48bSHardik T Shah  * config
753a0ffe48bSHardik T Shah  */
skl_set_src_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_src_module_cfg * src_mconfig)754bcc2a2dcSCezary Rojewski static void skl_set_src_format(struct skl_dev *skl,
755a0ffe48bSHardik T Shah 			struct skl_module_cfg *mconfig,
756a0ffe48bSHardik T Shah 			struct skl_src_module_cfg *src_mconfig)
757a0ffe48bSHardik T Shah {
758f6fa56e2SRamesh Babu 	struct skl_module *module = mconfig->module;
759f6fa56e2SRamesh Babu 	struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
760f6fa56e2SRamesh Babu 	struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
761a0ffe48bSHardik T Shah 
762bcc2a2dcSCezary Rojewski 	skl_set_base_module_format(skl, mconfig,
763a0ffe48bSHardik T Shah 		(struct skl_base_cfg *)src_mconfig);
764a0ffe48bSHardik T Shah 
765a0ffe48bSHardik T Shah 	src_mconfig->src_cfg = fmt->s_freq;
766a0ffe48bSHardik T Shah }
767a0ffe48bSHardik T Shah 
768a0ffe48bSHardik T Shah /*
769a0ffe48bSHardik T Shah  * DSP needs updown module to do channel conversion. updown module take base
770a0ffe48bSHardik T Shah  * module configuration and channel configuration
771a0ffe48bSHardik T Shah  * It also take coefficients and now we have defaults applied here
772a0ffe48bSHardik T Shah  */
skl_set_updown_mixer_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_up_down_mixer_cfg * mixer_mconfig)773bcc2a2dcSCezary Rojewski static void skl_set_updown_mixer_format(struct skl_dev *skl,
774a0ffe48bSHardik T Shah 			struct skl_module_cfg *mconfig,
775a0ffe48bSHardik T Shah 			struct skl_up_down_mixer_cfg *mixer_mconfig)
776a0ffe48bSHardik T Shah {
777f6fa56e2SRamesh Babu 	struct skl_module *module = mconfig->module;
778f6fa56e2SRamesh Babu 	struct skl_module_iface *iface = &module->formats[mconfig->fmt_idx];
779f6fa56e2SRamesh Babu 	struct skl_module_fmt *fmt = &iface->outputs[0].fmt;
780a0ffe48bSHardik T Shah 
781bcc2a2dcSCezary Rojewski 	skl_set_base_module_format(skl,	mconfig,
782a0ffe48bSHardik T Shah 		(struct skl_base_cfg *)mixer_mconfig);
783a0ffe48bSHardik T Shah 	mixer_mconfig->out_ch_cfg = fmt->ch_cfg;
784da3417feSGuneshwor Singh 	mixer_mconfig->ch_map = fmt->ch_map;
785a0ffe48bSHardik T Shah }
786a0ffe48bSHardik T Shah 
787a0ffe48bSHardik T Shah /*
78823db472bSJeeja KP  * 'copier' is DSP internal module which copies data from Host DMA (HDA host
78923db472bSJeeja KP  * dma) or link (hda link, SSP, PDM)
79023db472bSJeeja KP  * Here we calculate the copier module parameters, like PCM format, output
79123db472bSJeeja KP  * format, gateway settings
79223db472bSJeeja KP  * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg
79323db472bSJeeja KP  */
skl_set_copier_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_cpr_cfg * cpr_mconfig)794bcc2a2dcSCezary Rojewski static void skl_set_copier_format(struct skl_dev *skl,
79523db472bSJeeja KP 			struct skl_module_cfg *mconfig,
79623db472bSJeeja KP 			struct skl_cpr_cfg *cpr_mconfig)
79723db472bSJeeja KP {
79823db472bSJeeja KP 	struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt;
79923db472bSJeeja KP 	struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig;
80023db472bSJeeja KP 
801bcc2a2dcSCezary Rojewski 	skl_set_base_module_format(skl, mconfig, base_cfg);
80223db472bSJeeja KP 
803bcc2a2dcSCezary Rojewski 	skl_setup_out_format(skl, mconfig, out_fmt);
804bcc2a2dcSCezary Rojewski 	skl_setup_cpr_gateway_cfg(skl, mconfig, cpr_mconfig);
80523db472bSJeeja KP }
80623db472bSJeeja KP 
807399b210bSJeeja KP /*
808fd18110fSDharageswari R  * Mic select module allows selecting one or many input channels, thus
809fd18110fSDharageswari R  * acting as a demux.
810fd18110fSDharageswari R  *
811fd18110fSDharageswari R  * Mic select module take base module configuration and out-format
812fd18110fSDharageswari R  * configuration
813fd18110fSDharageswari R  */
skl_set_base_outfmt_format(struct skl_dev * skl,struct skl_module_cfg * mconfig,struct skl_base_outfmt_cfg * base_outfmt_mcfg)814bcc2a2dcSCezary Rojewski static void skl_set_base_outfmt_format(struct skl_dev *skl,
815fd18110fSDharageswari R 			struct skl_module_cfg *mconfig,
816fd18110fSDharageswari R 			struct skl_base_outfmt_cfg *base_outfmt_mcfg)
817fd18110fSDharageswari R {
818fd18110fSDharageswari R 	struct skl_audio_data_format *out_fmt = &base_outfmt_mcfg->out_fmt;
819fd18110fSDharageswari R 	struct skl_base_cfg *base_cfg =
820fd18110fSDharageswari R 				(struct skl_base_cfg *)base_outfmt_mcfg;
821fd18110fSDharageswari R 
822bcc2a2dcSCezary Rojewski 	skl_set_base_module_format(skl, mconfig, base_cfg);
823bcc2a2dcSCezary Rojewski 	skl_setup_out_format(skl, mconfig, out_fmt);
824fd18110fSDharageswari R }
825fd18110fSDharageswari R 
skl_get_module_param_size(struct skl_dev * skl,struct skl_module_cfg * mconfig)826bcc2a2dcSCezary Rojewski static u16 skl_get_module_param_size(struct skl_dev *skl,
82723db472bSJeeja KP 			struct skl_module_cfg *mconfig)
82823db472bSJeeja KP {
8295b27a71cSPawel Harlozinski 	struct skl_module_res *res;
8305b27a71cSPawel Harlozinski 	struct skl_module *module = mconfig->module;
83123db472bSJeeja KP 	u16 param_size;
83223db472bSJeeja KP 
83323db472bSJeeja KP 	switch (mconfig->m_type) {
83423db472bSJeeja KP 	case SKL_MODULE_TYPE_COPIER:
83523db472bSJeeja KP 		param_size = sizeof(struct skl_cpr_cfg);
836a4ad42d2SKareem Shaik 		param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
83723db472bSJeeja KP 		return param_size;
83823db472bSJeeja KP 
839a0ffe48bSHardik T Shah 	case SKL_MODULE_TYPE_SRCINT:
840a0ffe48bSHardik T Shah 		return sizeof(struct skl_src_module_cfg);
841a0ffe48bSHardik T Shah 
842a0ffe48bSHardik T Shah 	case SKL_MODULE_TYPE_UPDWMIX:
843a0ffe48bSHardik T Shah 		return sizeof(struct skl_up_down_mixer_cfg);
844a0ffe48bSHardik T Shah 
845fd18110fSDharageswari R 	case SKL_MODULE_TYPE_BASE_OUTFMT:
846db6879efSDharageswari R 	case SKL_MODULE_TYPE_MIC_SELECT:
847fd18110fSDharageswari R 		return sizeof(struct skl_base_outfmt_cfg);
848fd18110fSDharageswari R 
849e4e0633bSCezary Rojewski 	case SKL_MODULE_TYPE_MIXER:
850e4e0633bSCezary Rojewski 	case SKL_MODULE_TYPE_KPB:
851e4e0633bSCezary Rojewski 		return sizeof(struct skl_base_cfg);
852e4e0633bSCezary Rojewski 
8535b27a71cSPawel Harlozinski 	case SKL_MODULE_TYPE_ALGO:
85423db472bSJeeja KP 	default:
8555b27a71cSPawel Harlozinski 		res = &module->resources[mconfig->res_idx];
8565b27a71cSPawel Harlozinski 
8575b27a71cSPawel Harlozinski 		param_size = sizeof(struct skl_base_cfg) + sizeof(struct skl_base_cfg_ext);
8585b27a71cSPawel Harlozinski 		param_size += (res->nr_input_pins + res->nr_output_pins) *
8595b27a71cSPawel Harlozinski 			      sizeof(struct skl_pin_format);
8605b27a71cSPawel Harlozinski 		param_size += mconfig->formats_config[SKL_PARAM_INIT].caps_size;
8615b27a71cSPawel Harlozinski 
8625b27a71cSPawel Harlozinski 		return param_size;
86323db472bSJeeja KP 	}
86423db472bSJeeja KP 
86523db472bSJeeja KP 	return 0;
86623db472bSJeeja KP }
86723db472bSJeeja KP 
86823db472bSJeeja KP /*
869a0ffe48bSHardik T Shah  * DSP firmware supports various modules like copier, SRC, updown etc.
870a0ffe48bSHardik T Shah  * These modules required various parameters to be calculated and sent for
871a0ffe48bSHardik T Shah  * the module initialization to DSP. By default a generic module needs only
872a0ffe48bSHardik T Shah  * base module format configuration
87323db472bSJeeja KP  */
874a0ffe48bSHardik T Shah 
skl_set_module_format(struct skl_dev * skl,struct skl_module_cfg * module_config,u16 * module_config_size,void ** param_data)875bcc2a2dcSCezary Rojewski static int skl_set_module_format(struct skl_dev *skl,
87623db472bSJeeja KP 			struct skl_module_cfg *module_config,
87723db472bSJeeja KP 			u16 *module_config_size,
87823db472bSJeeja KP 			void **param_data)
87923db472bSJeeja KP {
88023db472bSJeeja KP 	u16 param_size;
88123db472bSJeeja KP 
882bcc2a2dcSCezary Rojewski 	param_size  = skl_get_module_param_size(skl, module_config);
88323db472bSJeeja KP 
88423db472bSJeeja KP 	*param_data = kzalloc(param_size, GFP_KERNEL);
88523db472bSJeeja KP 	if (NULL == *param_data)
88623db472bSJeeja KP 		return -ENOMEM;
88723db472bSJeeja KP 
88823db472bSJeeja KP 	*module_config_size = param_size;
88923db472bSJeeja KP 
89023db472bSJeeja KP 	switch (module_config->m_type) {
89123db472bSJeeja KP 	case SKL_MODULE_TYPE_COPIER:
892bcc2a2dcSCezary Rojewski 		skl_set_copier_format(skl, module_config, *param_data);
89323db472bSJeeja KP 		break;
89423db472bSJeeja KP 
895a0ffe48bSHardik T Shah 	case SKL_MODULE_TYPE_SRCINT:
896bcc2a2dcSCezary Rojewski 		skl_set_src_format(skl, module_config, *param_data);
897a0ffe48bSHardik T Shah 		break;
898a0ffe48bSHardik T Shah 
899a0ffe48bSHardik T Shah 	case SKL_MODULE_TYPE_UPDWMIX:
900bcc2a2dcSCezary Rojewski 		skl_set_updown_mixer_format(skl, module_config, *param_data);
901a0ffe48bSHardik T Shah 		break;
902a0ffe48bSHardik T Shah 
903fd18110fSDharageswari R 	case SKL_MODULE_TYPE_BASE_OUTFMT:
904db6879efSDharageswari R 	case SKL_MODULE_TYPE_MIC_SELECT:
905bcc2a2dcSCezary Rojewski 		skl_set_base_outfmt_format(skl, module_config, *param_data);
906fd18110fSDharageswari R 		break;
907fd18110fSDharageswari R 
908e4e0633bSCezary Rojewski 	case SKL_MODULE_TYPE_MIXER:
909e4e0633bSCezary Rojewski 	case SKL_MODULE_TYPE_KPB:
910e4e0633bSCezary Rojewski 		skl_set_base_module_format(skl, module_config, *param_data);
911e4e0633bSCezary Rojewski 		break;
912e4e0633bSCezary Rojewski 
9135b27a71cSPawel Harlozinski 	case SKL_MODULE_TYPE_ALGO:
91423db472bSJeeja KP 	default:
915bcc2a2dcSCezary Rojewski 		skl_set_base_module_format(skl, module_config, *param_data);
9165b27a71cSPawel Harlozinski 		skl_set_base_ext_module_format(skl, module_config,
9175b27a71cSPawel Harlozinski 					       *param_data +
9185b27a71cSPawel Harlozinski 					       sizeof(struct skl_base_cfg));
91923db472bSJeeja KP 		break;
92023db472bSJeeja KP 	}
92123db472bSJeeja KP 
9220cc33cecSAmadeusz Sławiński 	dev_dbg(skl->dev, "Module type=%d id=%d config size: %d bytes\n",
9230cc33cecSAmadeusz Sławiński 			module_config->m_type, module_config->id.module_id,
9240cc33cecSAmadeusz Sławiński 			param_size);
92591c18325SVedang Patel 	print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4,
92623db472bSJeeja KP 			*param_data, param_size, false);
92723db472bSJeeja KP 	return 0;
92823db472bSJeeja KP }
92923db472bSJeeja KP 
skl_get_queue_index(struct skl_module_pin * mpin,struct skl_module_inst_id id,int max)93023db472bSJeeja KP static int skl_get_queue_index(struct skl_module_pin *mpin,
93123db472bSJeeja KP 				struct skl_module_inst_id id, int max)
93223db472bSJeeja KP {
93323db472bSJeeja KP 	int i;
93423db472bSJeeja KP 
93523db472bSJeeja KP 	for (i = 0; i < max; i++)  {
93623db472bSJeeja KP 		if (mpin[i].id.module_id == id.module_id &&
93723db472bSJeeja KP 			mpin[i].id.instance_id == id.instance_id)
93823db472bSJeeja KP 			return i;
93923db472bSJeeja KP 	}
94023db472bSJeeja KP 
94123db472bSJeeja KP 	return -EINVAL;
94223db472bSJeeja KP }
94323db472bSJeeja KP 
94423db472bSJeeja KP /*
94523db472bSJeeja KP  * Allocates queue for each module.
94623db472bSJeeja KP  * if dynamic, the pin_index is allocated 0 to max_pin.
94723db472bSJeeja KP  * In static, the pin_index is fixed based on module_id and instance id
94823db472bSJeeja KP  */
skl_alloc_queue(struct skl_module_pin * mpin,struct skl_module_cfg * tgt_cfg,int max)94923db472bSJeeja KP static int skl_alloc_queue(struct skl_module_pin *mpin,
9504f745708SJeeja KP 			struct skl_module_cfg *tgt_cfg, int max)
95123db472bSJeeja KP {
95223db472bSJeeja KP 	int i;
9534f745708SJeeja KP 	struct skl_module_inst_id id = tgt_cfg->id;
95423db472bSJeeja KP 	/*
95523db472bSJeeja KP 	 * if pin in dynamic, find first free pin
95623db472bSJeeja KP 	 * otherwise find match module and instance id pin as topology will
95723db472bSJeeja KP 	 * ensure a unique pin is assigned to this so no need to
95823db472bSJeeja KP 	 * allocate/free
95923db472bSJeeja KP 	 */
96023db472bSJeeja KP 	for (i = 0; i < max; i++)  {
96123db472bSJeeja KP 		if (mpin[i].is_dynamic) {
9624f745708SJeeja KP 			if (!mpin[i].in_use &&
9634f745708SJeeja KP 				mpin[i].pin_state == SKL_PIN_UNBIND) {
9644f745708SJeeja KP 
96523db472bSJeeja KP 				mpin[i].in_use = true;
96623db472bSJeeja KP 				mpin[i].id.module_id = id.module_id;
96723db472bSJeeja KP 				mpin[i].id.instance_id = id.instance_id;
968ef2a352cSDharageswari R 				mpin[i].id.pvt_id = id.pvt_id;
9694f745708SJeeja KP 				mpin[i].tgt_mcfg = tgt_cfg;
97023db472bSJeeja KP 				return i;
97123db472bSJeeja KP 			}
97223db472bSJeeja KP 		} else {
97323db472bSJeeja KP 			if (mpin[i].id.module_id == id.module_id &&
9744f745708SJeeja KP 				mpin[i].id.instance_id == id.instance_id &&
9754f745708SJeeja KP 				mpin[i].pin_state == SKL_PIN_UNBIND) {
9764f745708SJeeja KP 
9774f745708SJeeja KP 				mpin[i].tgt_mcfg = tgt_cfg;
97823db472bSJeeja KP 				return i;
97923db472bSJeeja KP 			}
98023db472bSJeeja KP 		}
9814f745708SJeeja KP 	}
98223db472bSJeeja KP 
98323db472bSJeeja KP 	return -EINVAL;
98423db472bSJeeja KP }
98523db472bSJeeja KP 
skl_free_queue(struct skl_module_pin * mpin,int q_index)98623db472bSJeeja KP static void skl_free_queue(struct skl_module_pin *mpin, int q_index)
98723db472bSJeeja KP {
98823db472bSJeeja KP 	if (mpin[q_index].is_dynamic) {
98923db472bSJeeja KP 		mpin[q_index].in_use = false;
99023db472bSJeeja KP 		mpin[q_index].id.module_id = 0;
99123db472bSJeeja KP 		mpin[q_index].id.instance_id = 0;
992ef2a352cSDharageswari R 		mpin[q_index].id.pvt_id = 0;
99323db472bSJeeja KP 	}
9944f745708SJeeja KP 	mpin[q_index].pin_state = SKL_PIN_UNBIND;
9954f745708SJeeja KP 	mpin[q_index].tgt_mcfg = NULL;
9964f745708SJeeja KP }
9974f745708SJeeja KP 
9984f745708SJeeja KP /* Module state will be set to unint, if all the out pin state is UNBIND */
9994f745708SJeeja KP 
skl_clear_module_state(struct skl_module_pin * mpin,int max,struct skl_module_cfg * mcfg)10004f745708SJeeja KP static void skl_clear_module_state(struct skl_module_pin *mpin, int max,
10014f745708SJeeja KP 						struct skl_module_cfg *mcfg)
10024f745708SJeeja KP {
10034f745708SJeeja KP 	int i;
10044f745708SJeeja KP 	bool found = false;
10054f745708SJeeja KP 
10064f745708SJeeja KP 	for (i = 0; i < max; i++)  {
10074f745708SJeeja KP 		if (mpin[i].pin_state == SKL_PIN_UNBIND)
10084f745708SJeeja KP 			continue;
10094f745708SJeeja KP 		found = true;
10104f745708SJeeja KP 		break;
10114f745708SJeeja KP 	}
10124f745708SJeeja KP 
10134f745708SJeeja KP 	if (!found)
1014473a4d51SJeeja KP 		mcfg->m_state = SKL_MODULE_INIT_DONE;
10154f745708SJeeja KP 	return;
101623db472bSJeeja KP }
1017beb73b26SJeeja KP 
1018beb73b26SJeeja KP /*
1019beb73b26SJeeja KP  * A module needs to be instanataited in DSP. A mdoule is present in a
1020beb73b26SJeeja KP  * collection of module referred as a PIPE.
1021beb73b26SJeeja KP  * We first calculate the module format, based on module type and then
1022beb73b26SJeeja KP  * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper
1023beb73b26SJeeja KP  */
skl_init_module(struct skl_dev * skl,struct skl_module_cfg * mconfig)1024bcc2a2dcSCezary Rojewski int skl_init_module(struct skl_dev *skl,
10259939a9c3SJeeja KP 			struct skl_module_cfg *mconfig)
1026beb73b26SJeeja KP {
1027beb73b26SJeeja KP 	u16 module_config_size = 0;
1028beb73b26SJeeja KP 	void *param_data = NULL;
1029beb73b26SJeeja KP 	int ret;
1030beb73b26SJeeja KP 	struct skl_ipc_init_instance_msg msg;
1031beb73b26SJeeja KP 
1032bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: module_id = %d instance=%d\n", __func__,
1033ef2a352cSDharageswari R 		 mconfig->id.module_id, mconfig->id.pvt_id);
1034beb73b26SJeeja KP 
1035beb73b26SJeeja KP 	if (mconfig->pipe->state != SKL_PIPE_CREATED) {
1036bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Pipe not created state= %d pipe_id= %d\n",
1037beb73b26SJeeja KP 				 mconfig->pipe->state, mconfig->pipe->ppl_id);
1038beb73b26SJeeja KP 		return -EIO;
1039beb73b26SJeeja KP 	}
1040beb73b26SJeeja KP 
1041bcc2a2dcSCezary Rojewski 	ret = skl_set_module_format(skl, mconfig,
1042beb73b26SJeeja KP 			&module_config_size, &param_data);
1043beb73b26SJeeja KP 	if (ret < 0) {
1044bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to set module format ret=%d\n", ret);
1045beb73b26SJeeja KP 		return ret;
1046beb73b26SJeeja KP 	}
1047beb73b26SJeeja KP 
1048beb73b26SJeeja KP 	msg.module_id = mconfig->id.module_id;
1049ef2a352cSDharageswari R 	msg.instance_id = mconfig->id.pvt_id;
1050beb73b26SJeeja KP 	msg.ppl_instance_id = mconfig->pipe->ppl_id;
1051beb73b26SJeeja KP 	msg.param_data_size = module_config_size;
1052beb73b26SJeeja KP 	msg.core_id = mconfig->core_id;
10533d4006cdSSenthilnathan Veppur 	msg.domain = mconfig->domain;
1054beb73b26SJeeja KP 
1055bcc2a2dcSCezary Rojewski 	ret = skl_ipc_init_instance(&skl->ipc, &msg, param_data);
1056beb73b26SJeeja KP 	if (ret < 0) {
1057bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to init instance ret=%d\n", ret);
1058beb73b26SJeeja KP 		kfree(param_data);
1059beb73b26SJeeja KP 		return ret;
1060beb73b26SJeeja KP 	}
1061beb73b26SJeeja KP 	mconfig->m_state = SKL_MODULE_INIT_DONE;
106276222d6dSMousumi Jana 	kfree(param_data);
1063beb73b26SJeeja KP 	return ret;
1064beb73b26SJeeja KP }
1065beb73b26SJeeja KP 
skl_dump_bind_info(struct skl_dev * skl,struct skl_module_cfg * src_module,struct skl_module_cfg * dst_module)1066bcc2a2dcSCezary Rojewski static void skl_dump_bind_info(struct skl_dev *skl, struct skl_module_cfg
1067beb73b26SJeeja KP 	*src_module, struct skl_module_cfg *dst_module)
1068beb73b26SJeeja KP {
1069bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: src module_id = %d  src_instance=%d\n",
1070ef2a352cSDharageswari R 		__func__, src_module->id.module_id, src_module->id.pvt_id);
1071bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: dst_module=%d dst_instance=%d\n", __func__,
1072ef2a352cSDharageswari R 		 dst_module->id.module_id, dst_module->id.pvt_id);
1073beb73b26SJeeja KP 
1074bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "src_module state = %d dst module state = %d\n",
1075beb73b26SJeeja KP 		src_module->m_state, dst_module->m_state);
1076beb73b26SJeeja KP }
1077beb73b26SJeeja KP 
1078beb73b26SJeeja KP /*
1079beb73b26SJeeja KP  * On module freeup, we need to unbind the module with modules
1080beb73b26SJeeja KP  * it is already bind.
1081beb73b26SJeeja KP  * Find the pin allocated and unbind then using bind_unbind IPC
1082beb73b26SJeeja KP  */
skl_unbind_modules(struct skl_dev * skl,struct skl_module_cfg * src_mcfg,struct skl_module_cfg * dst_mcfg)1083bcc2a2dcSCezary Rojewski int skl_unbind_modules(struct skl_dev *skl,
1084beb73b26SJeeja KP 			struct skl_module_cfg *src_mcfg,
1085beb73b26SJeeja KP 			struct skl_module_cfg *dst_mcfg)
1086beb73b26SJeeja KP {
1087beb73b26SJeeja KP 	int ret;
1088beb73b26SJeeja KP 	struct skl_ipc_bind_unbind_msg msg;
1089beb73b26SJeeja KP 	struct skl_module_inst_id src_id = src_mcfg->id;
1090beb73b26SJeeja KP 	struct skl_module_inst_id dst_id = dst_mcfg->id;
1091f6fa56e2SRamesh Babu 	int in_max = dst_mcfg->module->max_input_pins;
1092f6fa56e2SRamesh Babu 	int out_max = src_mcfg->module->max_output_pins;
10934f745708SJeeja KP 	int src_index, dst_index, src_pin_state, dst_pin_state;
1094beb73b26SJeeja KP 
1095bcc2a2dcSCezary Rojewski 	skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
1096beb73b26SJeeja KP 
1097beb73b26SJeeja KP 	/* get src queue index */
1098beb73b26SJeeja KP 	src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max);
1099beb73b26SJeeja KP 	if (src_index < 0)
11009cf3049eSJeeja KP 		return 0;
1101beb73b26SJeeja KP 
11024f745708SJeeja KP 	msg.src_queue = src_index;
1103beb73b26SJeeja KP 
1104beb73b26SJeeja KP 	/* get dst queue index */
1105beb73b26SJeeja KP 	dst_index  = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max);
1106beb73b26SJeeja KP 	if (dst_index < 0)
11079cf3049eSJeeja KP 		return 0;
1108beb73b26SJeeja KP 
11094f745708SJeeja KP 	msg.dst_queue = dst_index;
11104f745708SJeeja KP 
11114f745708SJeeja KP 	src_pin_state = src_mcfg->m_out_pin[src_index].pin_state;
11124f745708SJeeja KP 	dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state;
11134f745708SJeeja KP 
11144f745708SJeeja KP 	if (src_pin_state != SKL_PIN_BIND_DONE ||
11154f745708SJeeja KP 		dst_pin_state != SKL_PIN_BIND_DONE)
11164f745708SJeeja KP 		return 0;
1117beb73b26SJeeja KP 
1118beb73b26SJeeja KP 	msg.module_id = src_mcfg->id.module_id;
1119ef2a352cSDharageswari R 	msg.instance_id = src_mcfg->id.pvt_id;
1120beb73b26SJeeja KP 	msg.dst_module_id = dst_mcfg->id.module_id;
1121ef2a352cSDharageswari R 	msg.dst_instance_id = dst_mcfg->id.pvt_id;
1122beb73b26SJeeja KP 	msg.bind = false;
1123beb73b26SJeeja KP 
1124bcc2a2dcSCezary Rojewski 	ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
1125beb73b26SJeeja KP 	if (!ret) {
1126beb73b26SJeeja KP 		/* free queue only if unbind is success */
1127beb73b26SJeeja KP 		skl_free_queue(src_mcfg->m_out_pin, src_index);
1128beb73b26SJeeja KP 		skl_free_queue(dst_mcfg->m_in_pin, dst_index);
11294f745708SJeeja KP 
11304f745708SJeeja KP 		/*
11314f745708SJeeja KP 		 * check only if src module bind state, bind is
11324f745708SJeeja KP 		 * always from src -> sink
11334f745708SJeeja KP 		 */
11344f745708SJeeja KP 		skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg);
1135beb73b26SJeeja KP 	}
1136beb73b26SJeeja KP 
1137beb73b26SJeeja KP 	return ret;
1138beb73b26SJeeja KP }
1139beb73b26SJeeja KP 
114038a77085SPradeep Tewani #define CPR_SINK_FMT_PARAM_ID 2
114138a77085SPradeep Tewani 
1142beb73b26SJeeja KP /*
1143beb73b26SJeeja KP  * Once a module is instantiated it need to be 'bind' with other modules in
1144beb73b26SJeeja KP  * the pipeline. For binding we need to find the module pins which are bind
1145beb73b26SJeeja KP  * together
1146beb73b26SJeeja KP  * This function finds the pins and then sends bund_unbind IPC message to
1147beb73b26SJeeja KP  * DSP using IPC helper
1148beb73b26SJeeja KP  */
skl_bind_modules(struct skl_dev * skl,struct skl_module_cfg * src_mcfg,struct skl_module_cfg * dst_mcfg)1149bcc2a2dcSCezary Rojewski int skl_bind_modules(struct skl_dev *skl,
1150beb73b26SJeeja KP 			struct skl_module_cfg *src_mcfg,
1151beb73b26SJeeja KP 			struct skl_module_cfg *dst_mcfg)
1152beb73b26SJeeja KP {
115338a77085SPradeep Tewani 	int ret = 0;
1154beb73b26SJeeja KP 	struct skl_ipc_bind_unbind_msg msg;
1155f6fa56e2SRamesh Babu 	int in_max = dst_mcfg->module->max_input_pins;
1156f6fa56e2SRamesh Babu 	int out_max = src_mcfg->module->max_output_pins;
1157beb73b26SJeeja KP 	int src_index, dst_index;
115838a77085SPradeep Tewani 	struct skl_module_fmt *format;
115938a77085SPradeep Tewani 	struct skl_cpr_pin_fmt pin_fmt;
116038a77085SPradeep Tewani 	struct skl_module *module;
116138a77085SPradeep Tewani 	struct skl_module_iface *fmt;
1162beb73b26SJeeja KP 
1163bcc2a2dcSCezary Rojewski 	skl_dump_bind_info(skl, src_mcfg, dst_mcfg);
1164beb73b26SJeeja KP 
11650c684c48SJeeja KP 	if (src_mcfg->m_state < SKL_MODULE_INIT_DONE ||
1166beb73b26SJeeja KP 		dst_mcfg->m_state < SKL_MODULE_INIT_DONE)
1167beb73b26SJeeja KP 		return 0;
1168beb73b26SJeeja KP 
11694f745708SJeeja KP 	src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max);
1170beb73b26SJeeja KP 	if (src_index < 0)
1171beb73b26SJeeja KP 		return -EINVAL;
1172beb73b26SJeeja KP 
11734f745708SJeeja KP 	msg.src_queue = src_index;
11744f745708SJeeja KP 	dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max);
1175beb73b26SJeeja KP 	if (dst_index < 0) {
1176beb73b26SJeeja KP 		skl_free_queue(src_mcfg->m_out_pin, src_index);
1177beb73b26SJeeja KP 		return -EINVAL;
1178beb73b26SJeeja KP 	}
1179beb73b26SJeeja KP 
118038a77085SPradeep Tewani 	/*
118138a77085SPradeep Tewani 	 * Copier module requires the separate large_config_set_ipc to
118238a77085SPradeep Tewani 	 * configure the pins other than 0
118338a77085SPradeep Tewani 	 */
118438a77085SPradeep Tewani 	if (src_mcfg->m_type == SKL_MODULE_TYPE_COPIER && src_index > 0) {
118538a77085SPradeep Tewani 		pin_fmt.sink_id = src_index;
118638a77085SPradeep Tewani 		module = src_mcfg->module;
118738a77085SPradeep Tewani 		fmt = &module->formats[src_mcfg->fmt_idx];
118838a77085SPradeep Tewani 
118938a77085SPradeep Tewani 		/* Input fmt is same as that of src module input cfg */
119038a77085SPradeep Tewani 		format = &fmt->inputs[0].fmt;
119138a77085SPradeep Tewani 		fill_pin_params(&(pin_fmt.src_fmt), format);
119238a77085SPradeep Tewani 
119338a77085SPradeep Tewani 		format = &fmt->outputs[src_index].fmt;
119438a77085SPradeep Tewani 		fill_pin_params(&(pin_fmt.dst_fmt), format);
1195bcc2a2dcSCezary Rojewski 		ret = skl_set_module_params(skl, (void *)&pin_fmt,
119638a77085SPradeep Tewani 					sizeof(struct skl_cpr_pin_fmt),
119738a77085SPradeep Tewani 					CPR_SINK_FMT_PARAM_ID, src_mcfg);
119838a77085SPradeep Tewani 
119938a77085SPradeep Tewani 		if (ret < 0)
120038a77085SPradeep Tewani 			goto out;
120138a77085SPradeep Tewani 	}
120238a77085SPradeep Tewani 
12034f745708SJeeja KP 	msg.dst_queue = dst_index;
1204beb73b26SJeeja KP 
1205bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "src queue = %d dst queue =%d\n",
1206beb73b26SJeeja KP 			 msg.src_queue, msg.dst_queue);
1207beb73b26SJeeja KP 
1208beb73b26SJeeja KP 	msg.module_id = src_mcfg->id.module_id;
1209ef2a352cSDharageswari R 	msg.instance_id = src_mcfg->id.pvt_id;
1210beb73b26SJeeja KP 	msg.dst_module_id = dst_mcfg->id.module_id;
1211ef2a352cSDharageswari R 	msg.dst_instance_id = dst_mcfg->id.pvt_id;
1212beb73b26SJeeja KP 	msg.bind = true;
1213beb73b26SJeeja KP 
1214bcc2a2dcSCezary Rojewski 	ret = skl_ipc_bind_unbind(&skl->ipc, &msg);
1215beb73b26SJeeja KP 
1216beb73b26SJeeja KP 	if (!ret) {
1217beb73b26SJeeja KP 		src_mcfg->m_state = SKL_MODULE_BIND_DONE;
12184f745708SJeeja KP 		src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE;
12194f745708SJeeja KP 		dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE;
122038a77085SPradeep Tewani 		return ret;
122138a77085SPradeep Tewani 	}
122238a77085SPradeep Tewani out:
1223beb73b26SJeeja KP 	/* error case , if IPC fails, clear the queue index */
1224beb73b26SJeeja KP 	skl_free_queue(src_mcfg->m_out_pin, src_index);
1225beb73b26SJeeja KP 	skl_free_queue(dst_mcfg->m_in_pin, dst_index);
1226beb73b26SJeeja KP 
1227beb73b26SJeeja KP 	return ret;
1228beb73b26SJeeja KP }
1229c9b1e834SJeeja KP 
skl_set_pipe_state(struct skl_dev * skl,struct skl_pipe * pipe,enum skl_ipc_pipeline_state state)1230bcc2a2dcSCezary Rojewski static int skl_set_pipe_state(struct skl_dev *skl, struct skl_pipe *pipe,
1231c9b1e834SJeeja KP 	enum skl_ipc_pipeline_state state)
1232c9b1e834SJeeja KP {
1233bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: pipe_state = %d\n", __func__, state);
1234c9b1e834SJeeja KP 
1235bcc2a2dcSCezary Rojewski 	return skl_ipc_set_pipeline_state(&skl->ipc, pipe->ppl_id, state);
1236c9b1e834SJeeja KP }
1237c9b1e834SJeeja KP 
1238c9b1e834SJeeja KP /*
1239c9b1e834SJeeja KP  * A pipeline is a collection of modules. Before a module in instantiated a
1240c9b1e834SJeeja KP  * pipeline needs to be created for it.
1241c9b1e834SJeeja KP  * This function creates pipeline, by sending create pipeline IPC messages
1242c9b1e834SJeeja KP  * to FW
1243c9b1e834SJeeja KP  */
skl_create_pipeline(struct skl_dev * skl,struct skl_pipe * pipe)1244bcc2a2dcSCezary Rojewski int skl_create_pipeline(struct skl_dev *skl, struct skl_pipe *pipe)
1245c9b1e834SJeeja KP {
1246c9b1e834SJeeja KP 	int ret;
1247c9b1e834SJeeja KP 
1248bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id);
1249c9b1e834SJeeja KP 
1250bcc2a2dcSCezary Rojewski 	ret = skl_ipc_create_pipeline(&skl->ipc, pipe->memory_pages,
12518a0cb236SVinod Koul 				pipe->pipe_priority, pipe->ppl_id,
12528a0cb236SVinod Koul 				pipe->lp_mode);
1253c9b1e834SJeeja KP 	if (ret < 0) {
1254bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to create pipeline\n");
1255c9b1e834SJeeja KP 		return ret;
1256c9b1e834SJeeja KP 	}
1257c9b1e834SJeeja KP 
1258c9b1e834SJeeja KP 	pipe->state = SKL_PIPE_CREATED;
1259c9b1e834SJeeja KP 
1260c9b1e834SJeeja KP 	return 0;
1261c9b1e834SJeeja KP }
1262c9b1e834SJeeja KP 
1263c9b1e834SJeeja KP /*
126402923faaSAmadeusz Sławiński  * A pipeline needs to be deleted on cleanup. If a pipeline is running,
126502923faaSAmadeusz Sławiński  * then pause it first. Before actual deletion, pipeline should enter
126602923faaSAmadeusz Sławiński  * reset state. Finish the procedure by sending delete pipeline IPC.
126702923faaSAmadeusz Sławiński  * DSP will stop the DMA engines and release resources
1268c9b1e834SJeeja KP  */
skl_delete_pipe(struct skl_dev * skl,struct skl_pipe * pipe)1269bcc2a2dcSCezary Rojewski int skl_delete_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1270c9b1e834SJeeja KP {
1271c9b1e834SJeeja KP 	int ret;
1272c9b1e834SJeeja KP 
1273bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1274c9b1e834SJeeja KP 
127502923faaSAmadeusz Sławiński 	/* If pipe was not created in FW, do not try to delete it */
127602923faaSAmadeusz Sławiński 	if (pipe->state < SKL_PIPE_CREATED)
127702923faaSAmadeusz Sławiński 		return 0;
127802923faaSAmadeusz Sławiński 
12791ae7ca04SDharageswari R 	/* If pipe is started, do stop the pipe in FW. */
12806914968bSJeeja KP 	if (pipe->state >= SKL_PIPE_STARTED) {
1281bcc2a2dcSCezary Rojewski 		ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
1282c9b1e834SJeeja KP 		if (ret < 0) {
1283bcc2a2dcSCezary Rojewski 			dev_err(skl->dev, "Failed to stop pipeline\n");
1284c9b1e834SJeeja KP 			return ret;
1285c9b1e834SJeeja KP 		}
1286c9b1e834SJeeja KP 
1287c9b1e834SJeeja KP 		pipe->state = SKL_PIPE_PAUSED;
12881ae7ca04SDharageswari R 	}
12891ae7ca04SDharageswari R 
129002923faaSAmadeusz Sławiński 	/* reset pipe state before deletion */
1291bcc2a2dcSCezary Rojewski 	ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
129202923faaSAmadeusz Sławiński 	if (ret < 0) {
1293bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to reset pipe ret=%d\n", ret);
129402923faaSAmadeusz Sławiński 		return ret;
129502923faaSAmadeusz Sławiński 	}
129602923faaSAmadeusz Sławiński 
129702923faaSAmadeusz Sławiński 	pipe->state = SKL_PIPE_RESET;
1298c9b1e834SJeeja KP 
1299bcc2a2dcSCezary Rojewski 	ret = skl_ipc_delete_pipeline(&skl->ipc, pipe->ppl_id);
13001ae7ca04SDharageswari R 	if (ret < 0) {
1301bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to delete pipeline\n");
13021ae7ca04SDharageswari R 		return ret;
13031ae7ca04SDharageswari R 	}
1304d2c7db85SJeeja KP 
1305d2c7db85SJeeja KP 	pipe->state = SKL_PIPE_INVALID;
1306c9b1e834SJeeja KP 
1307c9b1e834SJeeja KP 	return ret;
1308c9b1e834SJeeja KP }
1309c9b1e834SJeeja KP 
1310c9b1e834SJeeja KP /*
1311c9b1e834SJeeja KP  * A pipeline is also a scheduling entity in DSP which can be run, stopped
1312c9b1e834SJeeja KP  * For processing data the pipe need to be run by sending IPC set pipe state
1313c9b1e834SJeeja KP  * to DSP
1314c9b1e834SJeeja KP  */
skl_run_pipe(struct skl_dev * skl,struct skl_pipe * pipe)1315bcc2a2dcSCezary Rojewski int skl_run_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1316c9b1e834SJeeja KP {
1317c9b1e834SJeeja KP 	int ret;
1318c9b1e834SJeeja KP 
1319bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id);
1320c9b1e834SJeeja KP 
1321c9b1e834SJeeja KP 	/* If pipe was not created in FW, do not try to pause or delete */
1322c9b1e834SJeeja KP 	if (pipe->state < SKL_PIPE_CREATED)
1323c9b1e834SJeeja KP 		return 0;
1324c9b1e834SJeeja KP 
1325c9b1e834SJeeja KP 	/* Pipe has to be paused before it is started */
1326bcc2a2dcSCezary Rojewski 	ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
1327c9b1e834SJeeja KP 	if (ret < 0) {
1328bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to pause pipe\n");
1329c9b1e834SJeeja KP 		return ret;
1330c9b1e834SJeeja KP 	}
1331c9b1e834SJeeja KP 
1332c9b1e834SJeeja KP 	pipe->state = SKL_PIPE_PAUSED;
1333c9b1e834SJeeja KP 
1334bcc2a2dcSCezary Rojewski 	ret = skl_set_pipe_state(skl, pipe, PPL_RUNNING);
1335c9b1e834SJeeja KP 	if (ret < 0) {
1336bcc2a2dcSCezary Rojewski 		dev_err(skl->dev, "Failed to start pipe\n");
1337c9b1e834SJeeja KP 		return ret;
1338c9b1e834SJeeja KP 	}
1339c9b1e834SJeeja KP 
1340c9b1e834SJeeja KP 	pipe->state = SKL_PIPE_STARTED;
1341c9b1e834SJeeja KP 
1342c9b1e834SJeeja KP 	return 0;
1343c9b1e834SJeeja KP }
1344c9b1e834SJeeja KP 
1345c9b1e834SJeeja KP /*
1346c9b1e834SJeeja KP  * Stop the pipeline by sending set pipe state IPC
1347c9b1e834SJeeja KP  * DSP doesnt implement stop so we always send pause message
1348c9b1e834SJeeja KP  */
skl_stop_pipe(struct skl_dev * skl,struct skl_pipe * pipe)1349bcc2a2dcSCezary Rojewski int skl_stop_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
1350c9b1e834SJeeja KP {
1351c9b1e834SJeeja KP 	int ret;
1352c9b1e834SJeeja KP 
1353bcc2a2dcSCezary Rojewski 	dev_dbg(skl->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id);
1354c9b1e834SJeeja KP 
1355c9b1e834SJeeja KP 	/* If pipe was not created in FW, do not try to pause or delete */
1356c9b1e834SJeeja KP 	if (pipe->state < SKL_PIPE_PAUSED)
1357c9b1e834SJeeja KP 		return 0;
1358c9b1e834SJeeja KP 
1359bcc2a2dcSCezary Rojewski 	ret = skl_set_pipe_state(skl, pipe, PPL_PAUSED);
1360c9b1e834SJeeja KP 	if (ret < 0) {
1361bcc2a2dcSCezary Rojewski 		dev_dbg(skl->dev, "Failed to stop pipe\n");
1362c9b1e834SJeeja KP 		return ret;
1363c9b1e834SJeeja KP 	}
1364c9b1e834SJeeja KP 
1365353f72aaSJeeja KP 	pipe->state = SKL_PIPE_PAUSED;
1366c9b1e834SJeeja KP 
1367c9b1e834SJeeja KP 	return 0;
1368c9b1e834SJeeja KP }
13699939a9c3SJeeja KP 
13702004432fSJeeja KP /*
13712004432fSJeeja KP  * Reset the pipeline by sending set pipe state IPC this will reset the DMA
13722004432fSJeeja KP  * from the DSP side
13732004432fSJeeja KP  */
skl_reset_pipe(struct skl_dev * skl,struct skl_pipe * pipe)1374bcc2a2dcSCezary Rojewski int skl_reset_pipe(struct skl_dev *skl, struct skl_pipe *pipe)
13752004432fSJeeja KP {
13762004432fSJeeja KP 	int ret;
13772004432fSJeeja KP 
13782004432fSJeeja KP 	/* If pipe was not created in FW, do not try to pause or delete */
13792004432fSJeeja KP 	if (pipe->state < SKL_PIPE_PAUSED)
13802004432fSJeeja KP 		return 0;
13812004432fSJeeja KP 
1382bcc2a2dcSCezary Rojewski 	ret = skl_set_pipe_state(skl, pipe, PPL_RESET);
13832004432fSJeeja KP 	if (ret < 0) {
1384bcc2a2dcSCezary Rojewski 		dev_dbg(skl->dev, "Failed to reset pipe ret=%d\n", ret);
13852004432fSJeeja KP 		return ret;
13862004432fSJeeja KP 	}
13872004432fSJeeja KP 
13882004432fSJeeja KP 	pipe->state = SKL_PIPE_RESET;
13892004432fSJeeja KP 
13902004432fSJeeja KP 	return 0;
13912004432fSJeeja KP }
13922004432fSJeeja KP 
13939939a9c3SJeeja KP /* Algo parameter set helper function */
skl_set_module_params(struct skl_dev * skl,u32 * params,int size,u32 param_id,struct skl_module_cfg * mcfg)1394bcc2a2dcSCezary Rojewski int skl_set_module_params(struct skl_dev *skl, u32 *params, int size,
13959939a9c3SJeeja KP 				u32 param_id, struct skl_module_cfg *mcfg)
13969939a9c3SJeeja KP {
13979939a9c3SJeeja KP 	struct skl_ipc_large_config_msg msg;
13989939a9c3SJeeja KP 
13999939a9c3SJeeja KP 	msg.module_id = mcfg->id.module_id;
1400ef2a352cSDharageswari R 	msg.instance_id = mcfg->id.pvt_id;
14019939a9c3SJeeja KP 	msg.param_data_size = size;
14029939a9c3SJeeja KP 	msg.large_param_id = param_id;
14039939a9c3SJeeja KP 
1404bcc2a2dcSCezary Rojewski 	return skl_ipc_set_large_config(&skl->ipc, &msg, params);
14059939a9c3SJeeja KP }
14067d9f2911SOmair M Abdullah 
skl_get_module_params(struct skl_dev * skl,u32 * params,int size,u32 param_id,struct skl_module_cfg * mcfg)1407bcc2a2dcSCezary Rojewski int skl_get_module_params(struct skl_dev *skl, u32 *params, int size,
14087d9f2911SOmair M Abdullah 			  u32 param_id, struct skl_module_cfg *mcfg)
14097d9f2911SOmair M Abdullah {
14107d9f2911SOmair M Abdullah 	struct skl_ipc_large_config_msg msg;
141136004c42SCezary Rojewski 	size_t bytes = size;
14127d9f2911SOmair M Abdullah 
14137d9f2911SOmair M Abdullah 	msg.module_id = mcfg->id.module_id;
1414ef2a352cSDharageswari R 	msg.instance_id = mcfg->id.pvt_id;
14157d9f2911SOmair M Abdullah 	msg.param_data_size = size;
14167d9f2911SOmair M Abdullah 	msg.large_param_id = param_id;
14177d9f2911SOmair M Abdullah 
141836004c42SCezary Rojewski 	return skl_ipc_get_large_config(&skl->ipc, &msg, &params, &bytes);
14197d9f2911SOmair M Abdullah }
1420