1d255b095SJeeja KP /* 2d255b095SJeeja KP * skl-message.c - HDA DSP interface for FW registration, Pipe and Module 3d255b095SJeeja KP * configurations 4d255b095SJeeja KP * 5d255b095SJeeja KP * Copyright (C) 2015 Intel Corp 6d255b095SJeeja KP * Author:Rafal Redzimski <rafal.f.redzimski@intel.com> 7d255b095SJeeja KP * Jeeja KP <jeeja.kp@intel.com> 8d255b095SJeeja KP * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 9d255b095SJeeja KP * 10d255b095SJeeja KP * This program is free software; you can redistribute it and/or modify 11d255b095SJeeja KP * it under the terms of the GNU General Public License as version 2, as 12d255b095SJeeja KP * published by the Free Software Foundation. 13d255b095SJeeja KP * 14d255b095SJeeja KP * This program is distributed in the hope that it will be useful, but 15d255b095SJeeja KP * WITHOUT ANY WARRANTY; without even the implied warranty of 16d255b095SJeeja KP * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17d255b095SJeeja KP * General Public License for more details. 18d255b095SJeeja KP */ 19d255b095SJeeja KP 20d255b095SJeeja KP #include <linux/slab.h> 21d255b095SJeeja KP #include <linux/pci.h> 22d255b095SJeeja KP #include <sound/core.h> 23d255b095SJeeja KP #include <sound/pcm.h> 24d255b095SJeeja KP #include "skl-sst-dsp.h" 25d255b095SJeeja KP #include "skl-sst-ipc.h" 26d255b095SJeeja KP #include "skl.h" 27d255b095SJeeja KP #include "../common/sst-dsp.h" 28d255b095SJeeja KP #include "../common/sst-dsp-priv.h" 2923db472bSJeeja KP #include "skl-topology.h" 3023db472bSJeeja KP #include "skl-tplg-interface.h" 31d255b095SJeeja KP 32d255b095SJeeja KP static int skl_alloc_dma_buf(struct device *dev, 33d255b095SJeeja KP struct snd_dma_buffer *dmab, size_t size) 34d255b095SJeeja KP { 35d255b095SJeeja KP struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 36d255b095SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 37d255b095SJeeja KP 38d255b095SJeeja KP if (!bus) 39d255b095SJeeja KP return -ENODEV; 40d255b095SJeeja KP 41d255b095SJeeja KP return bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, size, dmab); 42d255b095SJeeja KP } 43d255b095SJeeja KP 44d255b095SJeeja KP static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab) 45d255b095SJeeja KP { 46d255b095SJeeja KP struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 47d255b095SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 48d255b095SJeeja KP 49d255b095SJeeja KP if (!bus) 50d255b095SJeeja KP return -ENODEV; 51d255b095SJeeja KP 52d255b095SJeeja KP bus->io_ops->dma_free_pages(bus, dmab); 53d255b095SJeeja KP 54d255b095SJeeja KP return 0; 55d255b095SJeeja KP } 56d255b095SJeeja KP 574e10996bSJeeja KP #define NOTIFICATION_PARAM_ID 3 584e10996bSJeeja KP #define NOTIFICATION_MASK 0xf 594e10996bSJeeja KP 604e10996bSJeeja KP /* disable notfication for underruns/overruns from firmware module */ 614e10996bSJeeja KP static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable) 624e10996bSJeeja KP { 634e10996bSJeeja KP struct notification_mask mask; 644e10996bSJeeja KP struct skl_ipc_large_config_msg msg = {0}; 654e10996bSJeeja KP 664e10996bSJeeja KP mask.notify = NOTIFICATION_MASK; 674e10996bSJeeja KP mask.enable = enable; 684e10996bSJeeja KP 694e10996bSJeeja KP msg.large_param_id = NOTIFICATION_PARAM_ID; 704e10996bSJeeja KP msg.param_data_size = sizeof(mask); 714e10996bSJeeja KP 724e10996bSJeeja KP skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask); 734e10996bSJeeja KP } 744e10996bSJeeja KP 7592eb4f62SJeeja KP static int skl_dsp_setup_spib(struct device *dev, unsigned int size, 7692eb4f62SJeeja KP int stream_tag, int enable) 7792eb4f62SJeeja KP { 7892eb4f62SJeeja KP struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 7992eb4f62SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 8092eb4f62SJeeja KP struct hdac_stream *stream = snd_hdac_get_stream(bus, 8192eb4f62SJeeja KP SNDRV_PCM_STREAM_PLAYBACK, stream_tag); 8292eb4f62SJeeja KP struct hdac_ext_stream *estream; 8392eb4f62SJeeja KP 8492eb4f62SJeeja KP if (!stream) 8592eb4f62SJeeja KP return -EINVAL; 8692eb4f62SJeeja KP 8792eb4f62SJeeja KP estream = stream_to_hdac_ext_stream(stream); 8892eb4f62SJeeja KP /* enable/disable SPIB for this hdac stream */ 8992eb4f62SJeeja KP snd_hdac_ext_stream_spbcap_enable(ebus, enable, stream->index); 9092eb4f62SJeeja KP 9192eb4f62SJeeja KP /* set the spib value */ 9292eb4f62SJeeja KP snd_hdac_ext_stream_set_spib(ebus, estream, size); 9392eb4f62SJeeja KP 9492eb4f62SJeeja KP return 0; 9592eb4f62SJeeja KP } 9692eb4f62SJeeja KP 9792eb4f62SJeeja KP static int skl_dsp_prepare(struct device *dev, unsigned int format, 9892eb4f62SJeeja KP unsigned int size, struct snd_dma_buffer *dmab) 9992eb4f62SJeeja KP { 10092eb4f62SJeeja KP struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 10192eb4f62SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 10292eb4f62SJeeja KP struct hdac_ext_stream *estream; 10392eb4f62SJeeja KP struct hdac_stream *stream; 10492eb4f62SJeeja KP struct snd_pcm_substream substream; 10592eb4f62SJeeja KP int ret; 10692eb4f62SJeeja KP 10792eb4f62SJeeja KP if (!bus) 10892eb4f62SJeeja KP return -ENODEV; 10992eb4f62SJeeja KP 11092eb4f62SJeeja KP memset(&substream, 0, sizeof(substream)); 11192eb4f62SJeeja KP substream.stream = SNDRV_PCM_STREAM_PLAYBACK; 11292eb4f62SJeeja KP 11392eb4f62SJeeja KP estream = snd_hdac_ext_stream_assign(ebus, &substream, 11492eb4f62SJeeja KP HDAC_EXT_STREAM_TYPE_HOST); 11592eb4f62SJeeja KP if (!estream) 11692eb4f62SJeeja KP return -ENODEV; 11792eb4f62SJeeja KP 11892eb4f62SJeeja KP stream = hdac_stream(estream); 11992eb4f62SJeeja KP 12092eb4f62SJeeja KP /* assign decouple host dma channel */ 12192eb4f62SJeeja KP ret = snd_hdac_dsp_prepare(stream, format, size, dmab); 12292eb4f62SJeeja KP if (ret < 0) 12392eb4f62SJeeja KP return ret; 12492eb4f62SJeeja KP 12592eb4f62SJeeja KP skl_dsp_setup_spib(dev, size, stream->stream_tag, true); 12692eb4f62SJeeja KP 12792eb4f62SJeeja KP return stream->stream_tag; 12892eb4f62SJeeja KP } 12992eb4f62SJeeja KP 13092eb4f62SJeeja KP static int skl_dsp_trigger(struct device *dev, bool start, int stream_tag) 13192eb4f62SJeeja KP { 13292eb4f62SJeeja KP struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 13392eb4f62SJeeja KP struct hdac_stream *stream; 13492eb4f62SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 13592eb4f62SJeeja KP 13692eb4f62SJeeja KP if (!bus) 13792eb4f62SJeeja KP return -ENODEV; 13892eb4f62SJeeja KP 13992eb4f62SJeeja KP stream = snd_hdac_get_stream(bus, 14092eb4f62SJeeja KP SNDRV_PCM_STREAM_PLAYBACK, stream_tag); 14192eb4f62SJeeja KP if (!stream) 14292eb4f62SJeeja KP return -EINVAL; 14392eb4f62SJeeja KP 14492eb4f62SJeeja KP snd_hdac_dsp_trigger(stream, start); 14592eb4f62SJeeja KP 14692eb4f62SJeeja KP return 0; 14792eb4f62SJeeja KP } 14892eb4f62SJeeja KP 14992eb4f62SJeeja KP static int skl_dsp_cleanup(struct device *dev, 15092eb4f62SJeeja KP struct snd_dma_buffer *dmab, int stream_tag) 15192eb4f62SJeeja KP { 15292eb4f62SJeeja KP struct hdac_ext_bus *ebus = dev_get_drvdata(dev); 15392eb4f62SJeeja KP struct hdac_stream *stream; 15492eb4f62SJeeja KP struct hdac_ext_stream *estream; 15592eb4f62SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 15692eb4f62SJeeja KP 15792eb4f62SJeeja KP if (!bus) 15892eb4f62SJeeja KP return -ENODEV; 15992eb4f62SJeeja KP 16092eb4f62SJeeja KP stream = snd_hdac_get_stream(bus, 16192eb4f62SJeeja KP SNDRV_PCM_STREAM_PLAYBACK, stream_tag); 16292eb4f62SJeeja KP if (!stream) 16392eb4f62SJeeja KP return -EINVAL; 16492eb4f62SJeeja KP 16592eb4f62SJeeja KP estream = stream_to_hdac_ext_stream(stream); 16692eb4f62SJeeja KP skl_dsp_setup_spib(dev, 0, stream_tag, false); 16792eb4f62SJeeja KP snd_hdac_ext_stream_release(estream, HDAC_EXT_STREAM_TYPE_HOST); 16892eb4f62SJeeja KP 16992eb4f62SJeeja KP snd_hdac_dsp_cleanup(stream, dmab); 17092eb4f62SJeeja KP 17192eb4f62SJeeja KP return 0; 17292eb4f62SJeeja KP } 17392eb4f62SJeeja KP 174bc23ca35SJeeja KP static struct skl_dsp_loader_ops skl_get_loader_ops(void) 175bc23ca35SJeeja KP { 176bc23ca35SJeeja KP struct skl_dsp_loader_ops loader_ops; 177bc23ca35SJeeja KP 178bc23ca35SJeeja KP memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops)); 179bc23ca35SJeeja KP 180bc23ca35SJeeja KP loader_ops.alloc_dma_buf = skl_alloc_dma_buf; 181bc23ca35SJeeja KP loader_ops.free_dma_buf = skl_free_dma_buf; 182bc23ca35SJeeja KP 183bc23ca35SJeeja KP return loader_ops; 184bc23ca35SJeeja KP }; 185bc23ca35SJeeja KP 18692eb4f62SJeeja KP static struct skl_dsp_loader_ops bxt_get_loader_ops(void) 18792eb4f62SJeeja KP { 18892eb4f62SJeeja KP struct skl_dsp_loader_ops loader_ops; 18992eb4f62SJeeja KP 19092eb4f62SJeeja KP memset(&loader_ops, 0, sizeof(loader_ops)); 19192eb4f62SJeeja KP 19292eb4f62SJeeja KP loader_ops.alloc_dma_buf = skl_alloc_dma_buf; 19392eb4f62SJeeja KP loader_ops.free_dma_buf = skl_free_dma_buf; 19492eb4f62SJeeja KP loader_ops.prepare = skl_dsp_prepare; 19592eb4f62SJeeja KP loader_ops.trigger = skl_dsp_trigger; 19692eb4f62SJeeja KP loader_ops.cleanup = skl_dsp_cleanup; 19792eb4f62SJeeja KP 19892eb4f62SJeeja KP return loader_ops; 19992eb4f62SJeeja KP }; 20092eb4f62SJeeja KP 201bc23ca35SJeeja KP static const struct skl_dsp_ops dsp_ops[] = { 202bc23ca35SJeeja KP { 203bc23ca35SJeeja KP .id = 0x9d70, 204bc23ca35SJeeja KP .loader_ops = skl_get_loader_ops, 205bc23ca35SJeeja KP .init = skl_sst_dsp_init, 20678cdbbdaSVinod Koul .init_fw = skl_sst_init_fw, 207bc23ca35SJeeja KP .cleanup = skl_sst_dsp_cleanup 208bc23ca35SJeeja KP }, 20992eb4f62SJeeja KP { 210451dfb5fSVinod Koul .id = 0x9d71, 211451dfb5fSVinod Koul .loader_ops = skl_get_loader_ops, 212451dfb5fSVinod Koul .init = skl_sst_dsp_init, 21378cdbbdaSVinod Koul .init_fw = skl_sst_init_fw, 214451dfb5fSVinod Koul .cleanup = skl_sst_dsp_cleanup 215451dfb5fSVinod Koul }, 216451dfb5fSVinod Koul { 21792eb4f62SJeeja KP .id = 0x5a98, 21892eb4f62SJeeja KP .loader_ops = bxt_get_loader_ops, 21992eb4f62SJeeja KP .init = bxt_sst_dsp_init, 22078cdbbdaSVinod Koul .init_fw = bxt_sst_init_fw, 22192eb4f62SJeeja KP .cleanup = bxt_sst_dsp_cleanup 22292eb4f62SJeeja KP }, 223bc23ca35SJeeja KP }; 224bc23ca35SJeeja KP 22573a67581SVinod Koul const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) 226bc23ca35SJeeja KP { 227bc23ca35SJeeja KP int i; 228bc23ca35SJeeja KP 229bc23ca35SJeeja KP for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { 230bc23ca35SJeeja KP if (dsp_ops[i].id == pci_id) 23173a67581SVinod Koul return &dsp_ops[i]; 232bc23ca35SJeeja KP } 233bc23ca35SJeeja KP 23473a67581SVinod Koul return NULL; 235bc23ca35SJeeja KP } 236bc23ca35SJeeja KP 237d255b095SJeeja KP int skl_init_dsp(struct skl *skl) 238d255b095SJeeja KP { 239d255b095SJeeja KP void __iomem *mmio_base; 240d255b095SJeeja KP struct hdac_ext_bus *ebus = &skl->ebus; 241d255b095SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 242d255b095SJeeja KP struct skl_dsp_loader_ops loader_ops; 243bc23ca35SJeeja KP int irq = bus->irq; 24473a67581SVinod Koul const struct skl_dsp_ops *ops; 24573a67581SVinod Koul int ret; 246d255b095SJeeja KP 247d255b095SJeeja KP /* enable ppcap interrupt */ 248d255b095SJeeja KP snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 249d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 250d255b095SJeeja KP 251d255b095SJeeja KP /* read the BAR of the ADSP MMIO */ 252d255b095SJeeja KP mmio_base = pci_ioremap_bar(skl->pci, 4); 253d255b095SJeeja KP if (mmio_base == NULL) { 254d255b095SJeeja KP dev_err(bus->dev, "ioremap error\n"); 255d255b095SJeeja KP return -ENXIO; 256d255b095SJeeja KP } 257d255b095SJeeja KP 25873a67581SVinod Koul ops = skl_get_dsp_ops(skl->pci->device); 25973a67581SVinod Koul if (!ops) 26073a67581SVinod Koul return -EIO; 261bc23ca35SJeeja KP 26273a67581SVinod Koul loader_ops = ops->loader_ops(); 26373a67581SVinod Koul ret = ops->init(bus->dev, mmio_base, irq, 26473a67581SVinod Koul skl->fw_name, loader_ops, 26573a67581SVinod Koul &skl->skl_sst); 266bc23ca35SJeeja KP 2672ac454ffSJeeja KP if (ret < 0) 2682ac454ffSJeeja KP return ret; 2692ac454ffSJeeja KP 270d255b095SJeeja KP dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 271d255b095SJeeja KP 272d255b095SJeeja KP return ret; 273d255b095SJeeja KP } 274d255b095SJeeja KP 275bc23ca35SJeeja KP int skl_free_dsp(struct skl *skl) 276d255b095SJeeja KP { 277d255b095SJeeja KP struct hdac_ext_bus *ebus = &skl->ebus; 278d255b095SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 279d255b095SJeeja KP struct skl_sst *ctx = skl->skl_sst; 28073a67581SVinod Koul const struct skl_dsp_ops *ops; 281d255b095SJeeja KP 282d255b095SJeeja KP /* disable ppcap interrupt */ 283d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 284d255b095SJeeja KP 28573a67581SVinod Koul ops = skl_get_dsp_ops(skl->pci->device); 28673a67581SVinod Koul if (!ops) 287bc23ca35SJeeja KP return -EIO; 288bc23ca35SJeeja KP 28973a67581SVinod Koul ops->cleanup(bus->dev, ctx); 290bc23ca35SJeeja KP 291d255b095SJeeja KP if (ctx->dsp->addr.lpe) 292d255b095SJeeja KP iounmap(ctx->dsp->addr.lpe); 293bc23ca35SJeeja KP 294bc23ca35SJeeja KP return 0; 295d255b095SJeeja KP } 296d255b095SJeeja KP 297d255b095SJeeja KP int skl_suspend_dsp(struct skl *skl) 298d255b095SJeeja KP { 299d255b095SJeeja KP struct skl_sst *ctx = skl->skl_sst; 300d255b095SJeeja KP int ret; 301d255b095SJeeja KP 302d255b095SJeeja KP /* if ppcap is not supported return 0 */ 303ec8ae570SVinod Koul if (!skl->ebus.bus.ppcap) 304d255b095SJeeja KP return 0; 305d255b095SJeeja KP 306d255b095SJeeja KP ret = skl_dsp_sleep(ctx->dsp); 307d255b095SJeeja KP if (ret < 0) 308d255b095SJeeja KP return ret; 309d255b095SJeeja KP 310d255b095SJeeja KP /* disable ppcap interrupt */ 311d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 312d255b095SJeeja KP snd_hdac_ext_bus_ppcap_enable(&skl->ebus, false); 313d255b095SJeeja KP 314d255b095SJeeja KP return 0; 315d255b095SJeeja KP } 316d255b095SJeeja KP 317d255b095SJeeja KP int skl_resume_dsp(struct skl *skl) 318d255b095SJeeja KP { 319d255b095SJeeja KP struct skl_sst *ctx = skl->skl_sst; 3204e10996bSJeeja KP int ret; 321d255b095SJeeja KP 322d255b095SJeeja KP /* if ppcap is not supported return 0 */ 323ec8ae570SVinod Koul if (!skl->ebus.bus.ppcap) 324d255b095SJeeja KP return 0; 325d255b095SJeeja KP 326d255b095SJeeja KP /* enable ppcap interrupt */ 327d255b095SJeeja KP snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 328d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 329d255b095SJeeja KP 33078cdbbdaSVinod Koul /* check if DSP 1st boot is done */ 33178cdbbdaSVinod Koul if (skl->skl_sst->is_first_boot == true) 33278cdbbdaSVinod Koul return 0; 33378cdbbdaSVinod Koul 3344e10996bSJeeja KP ret = skl_dsp_wake(ctx->dsp); 3354e10996bSJeeja KP if (ret < 0) 3364e10996bSJeeja KP return ret; 3374e10996bSJeeja KP 3384e10996bSJeeja KP skl_dsp_enable_notification(skl->skl_sst, false); 3394e10996bSJeeja KP return ret; 340d255b095SJeeja KP } 34123db472bSJeeja KP 34223db472bSJeeja KP enum skl_bitdepth skl_get_bit_depth(int params) 34323db472bSJeeja KP { 34423db472bSJeeja KP switch (params) { 34523db472bSJeeja KP case 8: 34623db472bSJeeja KP return SKL_DEPTH_8BIT; 34723db472bSJeeja KP 34823db472bSJeeja KP case 16: 34923db472bSJeeja KP return SKL_DEPTH_16BIT; 35023db472bSJeeja KP 35123db472bSJeeja KP case 24: 35223db472bSJeeja KP return SKL_DEPTH_24BIT; 35323db472bSJeeja KP 35423db472bSJeeja KP case 32: 35523db472bSJeeja KP return SKL_DEPTH_32BIT; 35623db472bSJeeja KP 35723db472bSJeeja KP default: 35823db472bSJeeja KP return SKL_DEPTH_INVALID; 35923db472bSJeeja KP 36023db472bSJeeja KP } 36123db472bSJeeja KP } 36223db472bSJeeja KP 36323db472bSJeeja KP /* 36423db472bSJeeja KP * Each module in DSP expects a base module configuration, which consists of 36523db472bSJeeja KP * PCM format information, which we calculate in driver and resource values 36623db472bSJeeja KP * which are read from widget information passed through topology binary 36723db472bSJeeja KP * This is send when we create a module with INIT_INSTANCE IPC msg 36823db472bSJeeja KP */ 36923db472bSJeeja KP static void skl_set_base_module_format(struct skl_sst *ctx, 37023db472bSJeeja KP struct skl_module_cfg *mconfig, 37123db472bSJeeja KP struct skl_base_cfg *base_cfg) 37223db472bSJeeja KP { 3734cd9899fSHardik T Shah struct skl_module_fmt *format = &mconfig->in_fmt[0]; 37423db472bSJeeja KP 37523db472bSJeeja KP base_cfg->audio_fmt.number_of_channels = (u8)format->channels; 37623db472bSJeeja KP 37723db472bSJeeja KP base_cfg->audio_fmt.s_freq = format->s_freq; 37823db472bSJeeja KP base_cfg->audio_fmt.bit_depth = format->bit_depth; 37923db472bSJeeja KP base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth; 38023db472bSJeeja KP base_cfg->audio_fmt.ch_cfg = format->ch_cfg; 38123db472bSJeeja KP 38223db472bSJeeja KP dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", 38323db472bSJeeja KP format->bit_depth, format->valid_bit_depth, 38423db472bSJeeja KP format->ch_cfg); 38523db472bSJeeja KP 3863e81f1a3SJeeja KP base_cfg->audio_fmt.channel_map = format->ch_map; 38723db472bSJeeja KP 3883e81f1a3SJeeja KP base_cfg->audio_fmt.interleaving = format->interleaving_style; 38923db472bSJeeja KP 39023db472bSJeeja KP base_cfg->cps = mconfig->mcps; 39123db472bSJeeja KP base_cfg->ibs = mconfig->ibs; 39223db472bSJeeja KP base_cfg->obs = mconfig->obs; 393b18c458dSJeeja KP base_cfg->is_pages = mconfig->mem_pages; 39423db472bSJeeja KP } 39523db472bSJeeja KP 39623db472bSJeeja KP /* 39723db472bSJeeja KP * Copies copier capabilities into copier module and updates copier module 39823db472bSJeeja KP * config size. 39923db472bSJeeja KP */ 40023db472bSJeeja KP static void skl_copy_copier_caps(struct skl_module_cfg *mconfig, 40123db472bSJeeja KP struct skl_cpr_cfg *cpr_mconfig) 40223db472bSJeeja KP { 40323db472bSJeeja KP if (mconfig->formats_config.caps_size == 0) 40423db472bSJeeja KP return; 40523db472bSJeeja KP 40623db472bSJeeja KP memcpy(cpr_mconfig->gtw_cfg.config_data, 40723db472bSJeeja KP mconfig->formats_config.caps, 40823db472bSJeeja KP mconfig->formats_config.caps_size); 40923db472bSJeeja KP 41023db472bSJeeja KP cpr_mconfig->gtw_cfg.config_length = 41123db472bSJeeja KP (mconfig->formats_config.caps_size) / 4; 41223db472bSJeeja KP } 41323db472bSJeeja KP 414bfa764acSJeeja KP #define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF 41523db472bSJeeja KP /* 41623db472bSJeeja KP * Calculate the gatewat settings required for copier module, type of 41723db472bSJeeja KP * gateway and index of gateway to use 41823db472bSJeeja KP */ 4194fdf810fSDharageswari.R static u32 skl_get_node_id(struct skl_sst *ctx, 4204fdf810fSDharageswari.R struct skl_module_cfg *mconfig) 42123db472bSJeeja KP { 42223db472bSJeeja KP union skl_connector_node_id node_id = {0}; 423d7b18813SJeeja KP union skl_ssp_dma_node ssp_node = {0}; 42423db472bSJeeja KP struct skl_pipe_params *params = mconfig->pipe->p_params; 42523db472bSJeeja KP 42623db472bSJeeja KP switch (mconfig->dev_type) { 42723db472bSJeeja KP case SKL_DEVICE_BT: 42823db472bSJeeja KP node_id.node.dma_type = 42923db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 43023db472bSJeeja KP SKL_DMA_I2S_LINK_OUTPUT_CLASS : 43123db472bSJeeja KP SKL_DMA_I2S_LINK_INPUT_CLASS; 43223db472bSJeeja KP node_id.node.vindex = params->host_dma_id + 43323db472bSJeeja KP (mconfig->vbus_id << 3); 43423db472bSJeeja KP break; 43523db472bSJeeja KP 43623db472bSJeeja KP case SKL_DEVICE_I2S: 43723db472bSJeeja KP node_id.node.dma_type = 43823db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 43923db472bSJeeja KP SKL_DMA_I2S_LINK_OUTPUT_CLASS : 44023db472bSJeeja KP SKL_DMA_I2S_LINK_INPUT_CLASS; 441d7b18813SJeeja KP ssp_node.dma_node.time_slot_index = mconfig->time_slot; 442d7b18813SJeeja KP ssp_node.dma_node.i2s_instance = mconfig->vbus_id; 443d7b18813SJeeja KP node_id.node.vindex = ssp_node.val; 44423db472bSJeeja KP break; 44523db472bSJeeja KP 44623db472bSJeeja KP case SKL_DEVICE_DMIC: 44723db472bSJeeja KP node_id.node.dma_type = SKL_DMA_DMIC_LINK_INPUT_CLASS; 44823db472bSJeeja KP node_id.node.vindex = mconfig->vbus_id + 44923db472bSJeeja KP (mconfig->time_slot); 45023db472bSJeeja KP break; 45123db472bSJeeja KP 45223db472bSJeeja KP case SKL_DEVICE_HDALINK: 45323db472bSJeeja KP node_id.node.dma_type = 45423db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 45523db472bSJeeja KP SKL_DMA_HDA_LINK_OUTPUT_CLASS : 45623db472bSJeeja KP SKL_DMA_HDA_LINK_INPUT_CLASS; 45723db472bSJeeja KP node_id.node.vindex = params->link_dma_id; 45823db472bSJeeja KP break; 45923db472bSJeeja KP 460bfa764acSJeeja KP case SKL_DEVICE_HDAHOST: 46123db472bSJeeja KP node_id.node.dma_type = 46223db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 46323db472bSJeeja KP SKL_DMA_HDA_HOST_OUTPUT_CLASS : 46423db472bSJeeja KP SKL_DMA_HDA_HOST_INPUT_CLASS; 46523db472bSJeeja KP node_id.node.vindex = params->host_dma_id; 46623db472bSJeeja KP break; 467bfa764acSJeeja KP 468bfa764acSJeeja KP default: 4694fdf810fSDharageswari.R node_id.val = 0xFFFFFFFF; 4704fdf810fSDharageswari.R break; 4714fdf810fSDharageswari.R } 4724fdf810fSDharageswari.R 4734fdf810fSDharageswari.R return node_id.val; 4744fdf810fSDharageswari.R } 4754fdf810fSDharageswari.R 4764fdf810fSDharageswari.R static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, 4774fdf810fSDharageswari.R struct skl_module_cfg *mconfig, 4784fdf810fSDharageswari.R struct skl_cpr_cfg *cpr_mconfig) 4794fdf810fSDharageswari.R { 4804fdf810fSDharageswari.R cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig); 4814fdf810fSDharageswari.R 4824fdf810fSDharageswari.R if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) { 483bfa764acSJeeja KP cpr_mconfig->cpr_feature_mask = 0; 484bfa764acSJeeja KP return; 48523db472bSJeeja KP } 48623db472bSJeeja KP 48723db472bSJeeja KP if (SKL_CONN_SOURCE == mconfig->hw_conn_type) 48823db472bSJeeja KP cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs; 48923db472bSJeeja KP else 49023db472bSJeeja KP cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->ibs; 49123db472bSJeeja KP 49223db472bSJeeja KP cpr_mconfig->cpr_feature_mask = 0; 49323db472bSJeeja KP cpr_mconfig->gtw_cfg.config_length = 0; 49423db472bSJeeja KP 49523db472bSJeeja KP skl_copy_copier_caps(mconfig, cpr_mconfig); 49623db472bSJeeja KP } 49723db472bSJeeja KP 498c115fa5eSDharageswari.R #define DMA_CONTROL_ID 5 499c115fa5eSDharageswari.R 500c115fa5eSDharageswari.R int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig) 501c115fa5eSDharageswari.R { 502c115fa5eSDharageswari.R struct skl_dma_control *dma_ctrl; 503c115fa5eSDharageswari.R struct skl_i2s_config_blob config_blob; 504c115fa5eSDharageswari.R struct skl_ipc_large_config_msg msg = {0}; 505c115fa5eSDharageswari.R int err = 0; 506c115fa5eSDharageswari.R 507c115fa5eSDharageswari.R 508c115fa5eSDharageswari.R /* 509c115fa5eSDharageswari.R * if blob size is same as capablity size, then no dma control 510c115fa5eSDharageswari.R * present so return 511c115fa5eSDharageswari.R */ 512c115fa5eSDharageswari.R if (mconfig->formats_config.caps_size == sizeof(config_blob)) 513c115fa5eSDharageswari.R return 0; 514c115fa5eSDharageswari.R 515c115fa5eSDharageswari.R msg.large_param_id = DMA_CONTROL_ID; 516c115fa5eSDharageswari.R msg.param_data_size = sizeof(struct skl_dma_control) + 517c115fa5eSDharageswari.R mconfig->formats_config.caps_size; 518c115fa5eSDharageswari.R 519c115fa5eSDharageswari.R dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL); 520c115fa5eSDharageswari.R if (dma_ctrl == NULL) 521c115fa5eSDharageswari.R return -ENOMEM; 522c115fa5eSDharageswari.R 523c115fa5eSDharageswari.R dma_ctrl->node_id = skl_get_node_id(ctx, mconfig); 524c115fa5eSDharageswari.R 525c115fa5eSDharageswari.R /* size in dwords */ 526c115fa5eSDharageswari.R dma_ctrl->config_length = sizeof(config_blob) / 4; 527c115fa5eSDharageswari.R 528c115fa5eSDharageswari.R memcpy(dma_ctrl->config_data, mconfig->formats_config.caps, 529c115fa5eSDharageswari.R mconfig->formats_config.caps_size); 530c115fa5eSDharageswari.R 531c115fa5eSDharageswari.R err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl); 532c115fa5eSDharageswari.R 533c115fa5eSDharageswari.R kfree(dma_ctrl); 534c115fa5eSDharageswari.R 535c115fa5eSDharageswari.R return err; 536c115fa5eSDharageswari.R } 537c115fa5eSDharageswari.R 53823db472bSJeeja KP static void skl_setup_out_format(struct skl_sst *ctx, 53923db472bSJeeja KP struct skl_module_cfg *mconfig, 54023db472bSJeeja KP struct skl_audio_data_format *out_fmt) 54123db472bSJeeja KP { 5424cd9899fSHardik T Shah struct skl_module_fmt *format = &mconfig->out_fmt[0]; 54323db472bSJeeja KP 54423db472bSJeeja KP out_fmt->number_of_channels = (u8)format->channels; 54523db472bSJeeja KP out_fmt->s_freq = format->s_freq; 54623db472bSJeeja KP out_fmt->bit_depth = format->bit_depth; 54723db472bSJeeja KP out_fmt->valid_bit_depth = format->valid_bit_depth; 54823db472bSJeeja KP out_fmt->ch_cfg = format->ch_cfg; 54923db472bSJeeja KP 5503e81f1a3SJeeja KP out_fmt->channel_map = format->ch_map; 5513e81f1a3SJeeja KP out_fmt->interleaving = format->interleaving_style; 5523e81f1a3SJeeja KP out_fmt->sample_type = format->sample_type; 55323db472bSJeeja KP 55423db472bSJeeja KP dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", 55523db472bSJeeja KP out_fmt->number_of_channels, format->s_freq, format->bit_depth); 55623db472bSJeeja KP } 55723db472bSJeeja KP 55823db472bSJeeja KP /* 559a0ffe48bSHardik T Shah * DSP needs SRC module for frequency conversion, SRC takes base module 560a0ffe48bSHardik T Shah * configuration and the target frequency as extra parameter passed as src 561a0ffe48bSHardik T Shah * config 562a0ffe48bSHardik T Shah */ 563a0ffe48bSHardik T Shah static void skl_set_src_format(struct skl_sst *ctx, 564a0ffe48bSHardik T Shah struct skl_module_cfg *mconfig, 565a0ffe48bSHardik T Shah struct skl_src_module_cfg *src_mconfig) 566a0ffe48bSHardik T Shah { 5674cd9899fSHardik T Shah struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; 568a0ffe48bSHardik T Shah 569a0ffe48bSHardik T Shah skl_set_base_module_format(ctx, mconfig, 570a0ffe48bSHardik T Shah (struct skl_base_cfg *)src_mconfig); 571a0ffe48bSHardik T Shah 572a0ffe48bSHardik T Shah src_mconfig->src_cfg = fmt->s_freq; 573a0ffe48bSHardik T Shah } 574a0ffe48bSHardik T Shah 575a0ffe48bSHardik T Shah /* 576a0ffe48bSHardik T Shah * DSP needs updown module to do channel conversion. updown module take base 577a0ffe48bSHardik T Shah * module configuration and channel configuration 578a0ffe48bSHardik T Shah * It also take coefficients and now we have defaults applied here 579a0ffe48bSHardik T Shah */ 580a0ffe48bSHardik T Shah static void skl_set_updown_mixer_format(struct skl_sst *ctx, 581a0ffe48bSHardik T Shah struct skl_module_cfg *mconfig, 582a0ffe48bSHardik T Shah struct skl_up_down_mixer_cfg *mixer_mconfig) 583a0ffe48bSHardik T Shah { 5844cd9899fSHardik T Shah struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; 585a0ffe48bSHardik T Shah int i = 0; 586a0ffe48bSHardik T Shah 587a0ffe48bSHardik T Shah skl_set_base_module_format(ctx, mconfig, 588a0ffe48bSHardik T Shah (struct skl_base_cfg *)mixer_mconfig); 589a0ffe48bSHardik T Shah mixer_mconfig->out_ch_cfg = fmt->ch_cfg; 590a0ffe48bSHardik T Shah 591a0ffe48bSHardik T Shah /* Select F/W default coefficient */ 592a0ffe48bSHardik T Shah mixer_mconfig->coeff_sel = 0x0; 593a0ffe48bSHardik T Shah 594a0ffe48bSHardik T Shah /* User coeff, don't care since we are selecting F/W defaults */ 595a0ffe48bSHardik T Shah for (i = 0; i < UP_DOWN_MIXER_MAX_COEFF; i++) 596a0ffe48bSHardik T Shah mixer_mconfig->coeff[i] = 0xDEADBEEF; 597a0ffe48bSHardik T Shah } 598a0ffe48bSHardik T Shah 599a0ffe48bSHardik T Shah /* 60023db472bSJeeja KP * 'copier' is DSP internal module which copies data from Host DMA (HDA host 60123db472bSJeeja KP * dma) or link (hda link, SSP, PDM) 60223db472bSJeeja KP * Here we calculate the copier module parameters, like PCM format, output 60323db472bSJeeja KP * format, gateway settings 60423db472bSJeeja KP * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg 60523db472bSJeeja KP */ 60623db472bSJeeja KP static void skl_set_copier_format(struct skl_sst *ctx, 60723db472bSJeeja KP struct skl_module_cfg *mconfig, 60823db472bSJeeja KP struct skl_cpr_cfg *cpr_mconfig) 60923db472bSJeeja KP { 61023db472bSJeeja KP struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt; 61123db472bSJeeja KP struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig; 61223db472bSJeeja KP 61323db472bSJeeja KP skl_set_base_module_format(ctx, mconfig, base_cfg); 61423db472bSJeeja KP 61523db472bSJeeja KP skl_setup_out_format(ctx, mconfig, out_fmt); 61623db472bSJeeja KP skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); 61723db472bSJeeja KP } 61823db472bSJeeja KP 619399b210bSJeeja KP /* 620399b210bSJeeja KP * Algo module are DSP pre processing modules. Algo module take base module 621399b210bSJeeja KP * configuration and params 622399b210bSJeeja KP */ 623399b210bSJeeja KP 624399b210bSJeeja KP static void skl_set_algo_format(struct skl_sst *ctx, 625399b210bSJeeja KP struct skl_module_cfg *mconfig, 626399b210bSJeeja KP struct skl_algo_cfg *algo_mcfg) 627399b210bSJeeja KP { 628399b210bSJeeja KP struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg; 629399b210bSJeeja KP 630399b210bSJeeja KP skl_set_base_module_format(ctx, mconfig, base_cfg); 631399b210bSJeeja KP 632399b210bSJeeja KP if (mconfig->formats_config.caps_size == 0) 633399b210bSJeeja KP return; 634399b210bSJeeja KP 635399b210bSJeeja KP memcpy(algo_mcfg->params, 636399b210bSJeeja KP mconfig->formats_config.caps, 637399b210bSJeeja KP mconfig->formats_config.caps_size); 638399b210bSJeeja KP 639399b210bSJeeja KP } 640399b210bSJeeja KP 641fd18110fSDharageswari R /* 642fd18110fSDharageswari R * Mic select module allows selecting one or many input channels, thus 643fd18110fSDharageswari R * acting as a demux. 644fd18110fSDharageswari R * 645fd18110fSDharageswari R * Mic select module take base module configuration and out-format 646fd18110fSDharageswari R * configuration 647fd18110fSDharageswari R */ 648fd18110fSDharageswari R static void skl_set_base_outfmt_format(struct skl_sst *ctx, 649fd18110fSDharageswari R struct skl_module_cfg *mconfig, 650fd18110fSDharageswari R struct skl_base_outfmt_cfg *base_outfmt_mcfg) 651fd18110fSDharageswari R { 652fd18110fSDharageswari R struct skl_audio_data_format *out_fmt = &base_outfmt_mcfg->out_fmt; 653fd18110fSDharageswari R struct skl_base_cfg *base_cfg = 654fd18110fSDharageswari R (struct skl_base_cfg *)base_outfmt_mcfg; 655fd18110fSDharageswari R 656fd18110fSDharageswari R skl_set_base_module_format(ctx, mconfig, base_cfg); 657fd18110fSDharageswari R skl_setup_out_format(ctx, mconfig, out_fmt); 658fd18110fSDharageswari R } 659fd18110fSDharageswari R 66023db472bSJeeja KP static u16 skl_get_module_param_size(struct skl_sst *ctx, 66123db472bSJeeja KP struct skl_module_cfg *mconfig) 66223db472bSJeeja KP { 66323db472bSJeeja KP u16 param_size; 66423db472bSJeeja KP 66523db472bSJeeja KP switch (mconfig->m_type) { 66623db472bSJeeja KP case SKL_MODULE_TYPE_COPIER: 66723db472bSJeeja KP param_size = sizeof(struct skl_cpr_cfg); 66823db472bSJeeja KP param_size += mconfig->formats_config.caps_size; 66923db472bSJeeja KP return param_size; 67023db472bSJeeja KP 671a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_SRCINT: 672a0ffe48bSHardik T Shah return sizeof(struct skl_src_module_cfg); 673a0ffe48bSHardik T Shah 674a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_UPDWMIX: 675a0ffe48bSHardik T Shah return sizeof(struct skl_up_down_mixer_cfg); 676a0ffe48bSHardik T Shah 677399b210bSJeeja KP case SKL_MODULE_TYPE_ALGO: 678399b210bSJeeja KP param_size = sizeof(struct skl_base_cfg); 679399b210bSJeeja KP param_size += mconfig->formats_config.caps_size; 680399b210bSJeeja KP return param_size; 681399b210bSJeeja KP 682fd18110fSDharageswari R case SKL_MODULE_TYPE_BASE_OUTFMT: 6835e8f0ee4SDharageswari R case SKL_MODULE_TYPE_KPB: 684fd18110fSDharageswari R return sizeof(struct skl_base_outfmt_cfg); 685fd18110fSDharageswari R 68623db472bSJeeja KP default: 68723db472bSJeeja KP /* 68823db472bSJeeja KP * return only base cfg when no specific module type is 68923db472bSJeeja KP * specified 69023db472bSJeeja KP */ 69123db472bSJeeja KP return sizeof(struct skl_base_cfg); 69223db472bSJeeja KP } 69323db472bSJeeja KP 69423db472bSJeeja KP return 0; 69523db472bSJeeja KP } 69623db472bSJeeja KP 69723db472bSJeeja KP /* 698a0ffe48bSHardik T Shah * DSP firmware supports various modules like copier, SRC, updown etc. 699a0ffe48bSHardik T Shah * These modules required various parameters to be calculated and sent for 700a0ffe48bSHardik T Shah * the module initialization to DSP. By default a generic module needs only 701a0ffe48bSHardik T Shah * base module format configuration 70223db472bSJeeja KP */ 703a0ffe48bSHardik T Shah 70423db472bSJeeja KP static int skl_set_module_format(struct skl_sst *ctx, 70523db472bSJeeja KP struct skl_module_cfg *module_config, 70623db472bSJeeja KP u16 *module_config_size, 70723db472bSJeeja KP void **param_data) 70823db472bSJeeja KP { 70923db472bSJeeja KP u16 param_size; 71023db472bSJeeja KP 71123db472bSJeeja KP param_size = skl_get_module_param_size(ctx, module_config); 71223db472bSJeeja KP 71323db472bSJeeja KP *param_data = kzalloc(param_size, GFP_KERNEL); 71423db472bSJeeja KP if (NULL == *param_data) 71523db472bSJeeja KP return -ENOMEM; 71623db472bSJeeja KP 71723db472bSJeeja KP *module_config_size = param_size; 71823db472bSJeeja KP 71923db472bSJeeja KP switch (module_config->m_type) { 72023db472bSJeeja KP case SKL_MODULE_TYPE_COPIER: 72123db472bSJeeja KP skl_set_copier_format(ctx, module_config, *param_data); 72223db472bSJeeja KP break; 72323db472bSJeeja KP 724a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_SRCINT: 725a0ffe48bSHardik T Shah skl_set_src_format(ctx, module_config, *param_data); 726a0ffe48bSHardik T Shah break; 727a0ffe48bSHardik T Shah 728a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_UPDWMIX: 729a0ffe48bSHardik T Shah skl_set_updown_mixer_format(ctx, module_config, *param_data); 730a0ffe48bSHardik T Shah break; 731a0ffe48bSHardik T Shah 732399b210bSJeeja KP case SKL_MODULE_TYPE_ALGO: 733399b210bSJeeja KP skl_set_algo_format(ctx, module_config, *param_data); 734399b210bSJeeja KP break; 735399b210bSJeeja KP 736fd18110fSDharageswari R case SKL_MODULE_TYPE_BASE_OUTFMT: 7375e8f0ee4SDharageswari R case SKL_MODULE_TYPE_KPB: 738fd18110fSDharageswari R skl_set_base_outfmt_format(ctx, module_config, *param_data); 739fd18110fSDharageswari R break; 740fd18110fSDharageswari R 74123db472bSJeeja KP default: 74223db472bSJeeja KP skl_set_base_module_format(ctx, module_config, *param_data); 74323db472bSJeeja KP break; 74423db472bSJeeja KP 74523db472bSJeeja KP } 74623db472bSJeeja KP 74723db472bSJeeja KP dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n", 74823db472bSJeeja KP module_config->id.module_id, param_size); 74991c18325SVedang Patel print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4, 75023db472bSJeeja KP *param_data, param_size, false); 75123db472bSJeeja KP return 0; 75223db472bSJeeja KP } 75323db472bSJeeja KP 75423db472bSJeeja KP static int skl_get_queue_index(struct skl_module_pin *mpin, 75523db472bSJeeja KP struct skl_module_inst_id id, int max) 75623db472bSJeeja KP { 75723db472bSJeeja KP int i; 75823db472bSJeeja KP 75923db472bSJeeja KP for (i = 0; i < max; i++) { 76023db472bSJeeja KP if (mpin[i].id.module_id == id.module_id && 76123db472bSJeeja KP mpin[i].id.instance_id == id.instance_id) 76223db472bSJeeja KP return i; 76323db472bSJeeja KP } 76423db472bSJeeja KP 76523db472bSJeeja KP return -EINVAL; 76623db472bSJeeja KP } 76723db472bSJeeja KP 76823db472bSJeeja KP /* 76923db472bSJeeja KP * Allocates queue for each module. 77023db472bSJeeja KP * if dynamic, the pin_index is allocated 0 to max_pin. 77123db472bSJeeja KP * In static, the pin_index is fixed based on module_id and instance id 77223db472bSJeeja KP */ 77323db472bSJeeja KP static int skl_alloc_queue(struct skl_module_pin *mpin, 7744f745708SJeeja KP struct skl_module_cfg *tgt_cfg, int max) 77523db472bSJeeja KP { 77623db472bSJeeja KP int i; 7774f745708SJeeja KP struct skl_module_inst_id id = tgt_cfg->id; 77823db472bSJeeja KP /* 77923db472bSJeeja KP * if pin in dynamic, find first free pin 78023db472bSJeeja KP * otherwise find match module and instance id pin as topology will 78123db472bSJeeja KP * ensure a unique pin is assigned to this so no need to 78223db472bSJeeja KP * allocate/free 78323db472bSJeeja KP */ 78423db472bSJeeja KP for (i = 0; i < max; i++) { 78523db472bSJeeja KP if (mpin[i].is_dynamic) { 7864f745708SJeeja KP if (!mpin[i].in_use && 7874f745708SJeeja KP mpin[i].pin_state == SKL_PIN_UNBIND) { 7884f745708SJeeja KP 78923db472bSJeeja KP mpin[i].in_use = true; 79023db472bSJeeja KP mpin[i].id.module_id = id.module_id; 79123db472bSJeeja KP mpin[i].id.instance_id = id.instance_id; 792ef2a352cSDharageswari R mpin[i].id.pvt_id = id.pvt_id; 7934f745708SJeeja KP mpin[i].tgt_mcfg = tgt_cfg; 79423db472bSJeeja KP return i; 79523db472bSJeeja KP } 79623db472bSJeeja KP } else { 79723db472bSJeeja KP if (mpin[i].id.module_id == id.module_id && 7984f745708SJeeja KP mpin[i].id.instance_id == id.instance_id && 7994f745708SJeeja KP mpin[i].pin_state == SKL_PIN_UNBIND) { 8004f745708SJeeja KP 8014f745708SJeeja KP mpin[i].tgt_mcfg = tgt_cfg; 80223db472bSJeeja KP return i; 80323db472bSJeeja KP } 80423db472bSJeeja KP } 8054f745708SJeeja KP } 80623db472bSJeeja KP 80723db472bSJeeja KP return -EINVAL; 80823db472bSJeeja KP } 80923db472bSJeeja KP 81023db472bSJeeja KP static void skl_free_queue(struct skl_module_pin *mpin, int q_index) 81123db472bSJeeja KP { 81223db472bSJeeja KP if (mpin[q_index].is_dynamic) { 81323db472bSJeeja KP mpin[q_index].in_use = false; 81423db472bSJeeja KP mpin[q_index].id.module_id = 0; 81523db472bSJeeja KP mpin[q_index].id.instance_id = 0; 816ef2a352cSDharageswari R mpin[q_index].id.pvt_id = 0; 81723db472bSJeeja KP } 8184f745708SJeeja KP mpin[q_index].pin_state = SKL_PIN_UNBIND; 8194f745708SJeeja KP mpin[q_index].tgt_mcfg = NULL; 8204f745708SJeeja KP } 8214f745708SJeeja KP 8224f745708SJeeja KP /* Module state will be set to unint, if all the out pin state is UNBIND */ 8234f745708SJeeja KP 8244f745708SJeeja KP static void skl_clear_module_state(struct skl_module_pin *mpin, int max, 8254f745708SJeeja KP struct skl_module_cfg *mcfg) 8264f745708SJeeja KP { 8274f745708SJeeja KP int i; 8284f745708SJeeja KP bool found = false; 8294f745708SJeeja KP 8304f745708SJeeja KP for (i = 0; i < max; i++) { 8314f745708SJeeja KP if (mpin[i].pin_state == SKL_PIN_UNBIND) 8324f745708SJeeja KP continue; 8334f745708SJeeja KP found = true; 8344f745708SJeeja KP break; 8354f745708SJeeja KP } 8364f745708SJeeja KP 8374f745708SJeeja KP if (!found) 8384f745708SJeeja KP mcfg->m_state = SKL_MODULE_UNINIT; 8394f745708SJeeja KP return; 84023db472bSJeeja KP } 841beb73b26SJeeja KP 842beb73b26SJeeja KP /* 843beb73b26SJeeja KP * A module needs to be instanataited in DSP. A mdoule is present in a 844beb73b26SJeeja KP * collection of module referred as a PIPE. 845beb73b26SJeeja KP * We first calculate the module format, based on module type and then 846beb73b26SJeeja KP * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper 847beb73b26SJeeja KP */ 848beb73b26SJeeja KP int skl_init_module(struct skl_sst *ctx, 8499939a9c3SJeeja KP struct skl_module_cfg *mconfig) 850beb73b26SJeeja KP { 851beb73b26SJeeja KP u16 module_config_size = 0; 852beb73b26SJeeja KP void *param_data = NULL; 853beb73b26SJeeja KP int ret; 854beb73b26SJeeja KP struct skl_ipc_init_instance_msg msg; 855beb73b26SJeeja KP 856beb73b26SJeeja KP dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, 857ef2a352cSDharageswari R mconfig->id.module_id, mconfig->id.pvt_id); 858beb73b26SJeeja KP 859beb73b26SJeeja KP if (mconfig->pipe->state != SKL_PIPE_CREATED) { 860beb73b26SJeeja KP dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", 861beb73b26SJeeja KP mconfig->pipe->state, mconfig->pipe->ppl_id); 862beb73b26SJeeja KP return -EIO; 863beb73b26SJeeja KP } 864beb73b26SJeeja KP 865beb73b26SJeeja KP ret = skl_set_module_format(ctx, mconfig, 866beb73b26SJeeja KP &module_config_size, ¶m_data); 867beb73b26SJeeja KP if (ret < 0) { 868beb73b26SJeeja KP dev_err(ctx->dev, "Failed to set module format ret=%d\n", ret); 869beb73b26SJeeja KP return ret; 870beb73b26SJeeja KP } 871beb73b26SJeeja KP 872beb73b26SJeeja KP msg.module_id = mconfig->id.module_id; 873ef2a352cSDharageswari R msg.instance_id = mconfig->id.pvt_id; 874beb73b26SJeeja KP msg.ppl_instance_id = mconfig->pipe->ppl_id; 875beb73b26SJeeja KP msg.param_data_size = module_config_size; 876beb73b26SJeeja KP msg.core_id = mconfig->core_id; 8773d4006cdSSenthilnathan Veppur msg.domain = mconfig->domain; 878beb73b26SJeeja KP 879beb73b26SJeeja KP ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); 880beb73b26SJeeja KP if (ret < 0) { 881beb73b26SJeeja KP dev_err(ctx->dev, "Failed to init instance ret=%d\n", ret); 882beb73b26SJeeja KP kfree(param_data); 883beb73b26SJeeja KP return ret; 884beb73b26SJeeja KP } 885beb73b26SJeeja KP mconfig->m_state = SKL_MODULE_INIT_DONE; 88676222d6dSMousumi Jana kfree(param_data); 887beb73b26SJeeja KP return ret; 888beb73b26SJeeja KP } 889beb73b26SJeeja KP 890beb73b26SJeeja KP static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg 891beb73b26SJeeja KP *src_module, struct skl_module_cfg *dst_module) 892beb73b26SJeeja KP { 893beb73b26SJeeja KP dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", 894ef2a352cSDharageswari R __func__, src_module->id.module_id, src_module->id.pvt_id); 895beb73b26SJeeja KP dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, 896ef2a352cSDharageswari R dst_module->id.module_id, dst_module->id.pvt_id); 897beb73b26SJeeja KP 898beb73b26SJeeja KP dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", 899beb73b26SJeeja KP src_module->m_state, dst_module->m_state); 900beb73b26SJeeja KP } 901beb73b26SJeeja KP 902beb73b26SJeeja KP /* 903beb73b26SJeeja KP * On module freeup, we need to unbind the module with modules 904beb73b26SJeeja KP * it is already bind. 905beb73b26SJeeja KP * Find the pin allocated and unbind then using bind_unbind IPC 906beb73b26SJeeja KP */ 907beb73b26SJeeja KP int skl_unbind_modules(struct skl_sst *ctx, 908beb73b26SJeeja KP struct skl_module_cfg *src_mcfg, 909beb73b26SJeeja KP struct skl_module_cfg *dst_mcfg) 910beb73b26SJeeja KP { 911beb73b26SJeeja KP int ret; 912beb73b26SJeeja KP struct skl_ipc_bind_unbind_msg msg; 913beb73b26SJeeja KP struct skl_module_inst_id src_id = src_mcfg->id; 914beb73b26SJeeja KP struct skl_module_inst_id dst_id = dst_mcfg->id; 915beb73b26SJeeja KP int in_max = dst_mcfg->max_in_queue; 916beb73b26SJeeja KP int out_max = src_mcfg->max_out_queue; 9174f745708SJeeja KP int src_index, dst_index, src_pin_state, dst_pin_state; 918beb73b26SJeeja KP 919beb73b26SJeeja KP skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 920beb73b26SJeeja KP 921beb73b26SJeeja KP /* get src queue index */ 922beb73b26SJeeja KP src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); 923beb73b26SJeeja KP if (src_index < 0) 9249cf3049eSJeeja KP return 0; 925beb73b26SJeeja KP 9264f745708SJeeja KP msg.src_queue = src_index; 927beb73b26SJeeja KP 928beb73b26SJeeja KP /* get dst queue index */ 929beb73b26SJeeja KP dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); 930beb73b26SJeeja KP if (dst_index < 0) 9319cf3049eSJeeja KP return 0; 932beb73b26SJeeja KP 9334f745708SJeeja KP msg.dst_queue = dst_index; 9344f745708SJeeja KP 9354f745708SJeeja KP src_pin_state = src_mcfg->m_out_pin[src_index].pin_state; 9364f745708SJeeja KP dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state; 9374f745708SJeeja KP 9384f745708SJeeja KP if (src_pin_state != SKL_PIN_BIND_DONE || 9394f745708SJeeja KP dst_pin_state != SKL_PIN_BIND_DONE) 9404f745708SJeeja KP return 0; 941beb73b26SJeeja KP 942beb73b26SJeeja KP msg.module_id = src_mcfg->id.module_id; 943ef2a352cSDharageswari R msg.instance_id = src_mcfg->id.pvt_id; 944beb73b26SJeeja KP msg.dst_module_id = dst_mcfg->id.module_id; 945ef2a352cSDharageswari R msg.dst_instance_id = dst_mcfg->id.pvt_id; 946beb73b26SJeeja KP msg.bind = false; 947beb73b26SJeeja KP 948beb73b26SJeeja KP ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 949beb73b26SJeeja KP if (!ret) { 950beb73b26SJeeja KP /* free queue only if unbind is success */ 951beb73b26SJeeja KP skl_free_queue(src_mcfg->m_out_pin, src_index); 952beb73b26SJeeja KP skl_free_queue(dst_mcfg->m_in_pin, dst_index); 9534f745708SJeeja KP 9544f745708SJeeja KP /* 9554f745708SJeeja KP * check only if src module bind state, bind is 9564f745708SJeeja KP * always from src -> sink 9574f745708SJeeja KP */ 9584f745708SJeeja KP skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg); 959beb73b26SJeeja KP } 960beb73b26SJeeja KP 961beb73b26SJeeja KP return ret; 962beb73b26SJeeja KP } 963beb73b26SJeeja KP 964beb73b26SJeeja KP /* 965beb73b26SJeeja KP * Once a module is instantiated it need to be 'bind' with other modules in 966beb73b26SJeeja KP * the pipeline. For binding we need to find the module pins which are bind 967beb73b26SJeeja KP * together 968beb73b26SJeeja KP * This function finds the pins and then sends bund_unbind IPC message to 969beb73b26SJeeja KP * DSP using IPC helper 970beb73b26SJeeja KP */ 971beb73b26SJeeja KP int skl_bind_modules(struct skl_sst *ctx, 972beb73b26SJeeja KP struct skl_module_cfg *src_mcfg, 973beb73b26SJeeja KP struct skl_module_cfg *dst_mcfg) 974beb73b26SJeeja KP { 975beb73b26SJeeja KP int ret; 976beb73b26SJeeja KP struct skl_ipc_bind_unbind_msg msg; 977beb73b26SJeeja KP int in_max = dst_mcfg->max_in_queue; 978beb73b26SJeeja KP int out_max = src_mcfg->max_out_queue; 979beb73b26SJeeja KP int src_index, dst_index; 980beb73b26SJeeja KP 981beb73b26SJeeja KP skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 982beb73b26SJeeja KP 9830c684c48SJeeja KP if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || 984beb73b26SJeeja KP dst_mcfg->m_state < SKL_MODULE_INIT_DONE) 985beb73b26SJeeja KP return 0; 986beb73b26SJeeja KP 9874f745708SJeeja KP src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max); 988beb73b26SJeeja KP if (src_index < 0) 989beb73b26SJeeja KP return -EINVAL; 990beb73b26SJeeja KP 9914f745708SJeeja KP msg.src_queue = src_index; 9924f745708SJeeja KP dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max); 993beb73b26SJeeja KP if (dst_index < 0) { 994beb73b26SJeeja KP skl_free_queue(src_mcfg->m_out_pin, src_index); 995beb73b26SJeeja KP return -EINVAL; 996beb73b26SJeeja KP } 997beb73b26SJeeja KP 9984f745708SJeeja KP msg.dst_queue = dst_index; 999beb73b26SJeeja KP 1000beb73b26SJeeja KP dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", 1001beb73b26SJeeja KP msg.src_queue, msg.dst_queue); 1002beb73b26SJeeja KP 1003beb73b26SJeeja KP msg.module_id = src_mcfg->id.module_id; 1004ef2a352cSDharageswari R msg.instance_id = src_mcfg->id.pvt_id; 1005beb73b26SJeeja KP msg.dst_module_id = dst_mcfg->id.module_id; 1006ef2a352cSDharageswari R msg.dst_instance_id = dst_mcfg->id.pvt_id; 1007beb73b26SJeeja KP msg.bind = true; 1008beb73b26SJeeja KP 1009beb73b26SJeeja KP ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 1010beb73b26SJeeja KP 1011beb73b26SJeeja KP if (!ret) { 1012beb73b26SJeeja KP src_mcfg->m_state = SKL_MODULE_BIND_DONE; 10134f745708SJeeja KP src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; 10144f745708SJeeja KP dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; 1015beb73b26SJeeja KP } else { 1016beb73b26SJeeja KP /* error case , if IPC fails, clear the queue index */ 1017beb73b26SJeeja KP skl_free_queue(src_mcfg->m_out_pin, src_index); 1018beb73b26SJeeja KP skl_free_queue(dst_mcfg->m_in_pin, dst_index); 1019beb73b26SJeeja KP } 1020beb73b26SJeeja KP 1021beb73b26SJeeja KP return ret; 1022beb73b26SJeeja KP } 1023c9b1e834SJeeja KP 1024c9b1e834SJeeja KP static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe, 1025c9b1e834SJeeja KP enum skl_ipc_pipeline_state state) 1026c9b1e834SJeeja KP { 1027c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe_satate = %d\n", __func__, state); 1028c9b1e834SJeeja KP 1029c9b1e834SJeeja KP return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state); 1030c9b1e834SJeeja KP } 1031c9b1e834SJeeja KP 1032c9b1e834SJeeja KP /* 1033c9b1e834SJeeja KP * A pipeline is a collection of modules. Before a module in instantiated a 1034c9b1e834SJeeja KP * pipeline needs to be created for it. 1035c9b1e834SJeeja KP * This function creates pipeline, by sending create pipeline IPC messages 1036c9b1e834SJeeja KP * to FW 1037c9b1e834SJeeja KP */ 1038c9b1e834SJeeja KP int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe) 1039c9b1e834SJeeja KP { 1040c9b1e834SJeeja KP int ret; 1041c9b1e834SJeeja KP 1042c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id); 1043c9b1e834SJeeja KP 1044c9b1e834SJeeja KP ret = skl_ipc_create_pipeline(&ctx->ipc, pipe->memory_pages, 1045c9b1e834SJeeja KP pipe->pipe_priority, pipe->ppl_id); 1046c9b1e834SJeeja KP if (ret < 0) { 1047c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to create pipeline\n"); 1048c9b1e834SJeeja KP return ret; 1049c9b1e834SJeeja KP } 1050c9b1e834SJeeja KP 1051c9b1e834SJeeja KP pipe->state = SKL_PIPE_CREATED; 1052c9b1e834SJeeja KP 1053c9b1e834SJeeja KP return 0; 1054c9b1e834SJeeja KP } 1055c9b1e834SJeeja KP 1056c9b1e834SJeeja KP /* 1057c9b1e834SJeeja KP * A pipeline needs to be deleted on cleanup. If a pipeline is running, then 1058c9b1e834SJeeja KP * pause the pipeline first and then delete it 1059c9b1e834SJeeja KP * The pipe delete is done by sending delete pipeline IPC. DSP will stop the 1060c9b1e834SJeeja KP * DMA engines and releases resources 1061c9b1e834SJeeja KP */ 1062c9b1e834SJeeja KP int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1063c9b1e834SJeeja KP { 1064c9b1e834SJeeja KP int ret; 1065c9b1e834SJeeja KP 1066c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1067c9b1e834SJeeja KP 10681ae7ca04SDharageswari R /* If pipe is started, do stop the pipe in FW. */ 1069c9b1e834SJeeja KP if (pipe->state > SKL_PIPE_STARTED) { 1070c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1071c9b1e834SJeeja KP if (ret < 0) { 1072c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to stop pipeline\n"); 1073c9b1e834SJeeja KP return ret; 1074c9b1e834SJeeja KP } 1075c9b1e834SJeeja KP 1076c9b1e834SJeeja KP pipe->state = SKL_PIPE_PAUSED; 10771ae7ca04SDharageswari R } 10781ae7ca04SDharageswari R 1079c9b1e834SJeeja KP /* If pipe was not created in FW, do not try to delete it */ 1080c9b1e834SJeeja KP if (pipe->state < SKL_PIPE_CREATED) 1081c9b1e834SJeeja KP return 0; 1082c9b1e834SJeeja KP 1083c9b1e834SJeeja KP ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); 10841ae7ca04SDharageswari R if (ret < 0) { 1085c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to delete pipeline\n"); 10861ae7ca04SDharageswari R return ret; 10871ae7ca04SDharageswari R } 1088d2c7db85SJeeja KP 1089d2c7db85SJeeja KP pipe->state = SKL_PIPE_INVALID; 1090c9b1e834SJeeja KP 1091c9b1e834SJeeja KP return ret; 1092c9b1e834SJeeja KP } 1093c9b1e834SJeeja KP 1094c9b1e834SJeeja KP /* 1095c9b1e834SJeeja KP * A pipeline is also a scheduling entity in DSP which can be run, stopped 1096c9b1e834SJeeja KP * For processing data the pipe need to be run by sending IPC set pipe state 1097c9b1e834SJeeja KP * to DSP 1098c9b1e834SJeeja KP */ 1099c9b1e834SJeeja KP int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1100c9b1e834SJeeja KP { 1101c9b1e834SJeeja KP int ret; 1102c9b1e834SJeeja KP 1103c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1104c9b1e834SJeeja KP 1105c9b1e834SJeeja KP /* If pipe was not created in FW, do not try to pause or delete */ 1106c9b1e834SJeeja KP if (pipe->state < SKL_PIPE_CREATED) 1107c9b1e834SJeeja KP return 0; 1108c9b1e834SJeeja KP 1109c9b1e834SJeeja KP /* Pipe has to be paused before it is started */ 1110c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1111c9b1e834SJeeja KP if (ret < 0) { 1112c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to pause pipe\n"); 1113c9b1e834SJeeja KP return ret; 1114c9b1e834SJeeja KP } 1115c9b1e834SJeeja KP 1116c9b1e834SJeeja KP pipe->state = SKL_PIPE_PAUSED; 1117c9b1e834SJeeja KP 1118c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_RUNNING); 1119c9b1e834SJeeja KP if (ret < 0) { 1120c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to start pipe\n"); 1121c9b1e834SJeeja KP return ret; 1122c9b1e834SJeeja KP } 1123c9b1e834SJeeja KP 1124c9b1e834SJeeja KP pipe->state = SKL_PIPE_STARTED; 1125c9b1e834SJeeja KP 1126c9b1e834SJeeja KP return 0; 1127c9b1e834SJeeja KP } 1128c9b1e834SJeeja KP 1129c9b1e834SJeeja KP /* 1130c9b1e834SJeeja KP * Stop the pipeline by sending set pipe state IPC 1131c9b1e834SJeeja KP * DSP doesnt implement stop so we always send pause message 1132c9b1e834SJeeja KP */ 1133c9b1e834SJeeja KP int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1134c9b1e834SJeeja KP { 1135c9b1e834SJeeja KP int ret; 1136c9b1e834SJeeja KP 1137c9b1e834SJeeja KP dev_dbg(ctx->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id); 1138c9b1e834SJeeja KP 1139c9b1e834SJeeja KP /* If pipe was not created in FW, do not try to pause or delete */ 1140c9b1e834SJeeja KP if (pipe->state < SKL_PIPE_PAUSED) 1141c9b1e834SJeeja KP return 0; 1142c9b1e834SJeeja KP 1143c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1144c9b1e834SJeeja KP if (ret < 0) { 1145c9b1e834SJeeja KP dev_dbg(ctx->dev, "Failed to stop pipe\n"); 1146c9b1e834SJeeja KP return ret; 1147c9b1e834SJeeja KP } 1148c9b1e834SJeeja KP 1149353f72aaSJeeja KP pipe->state = SKL_PIPE_PAUSED; 1150c9b1e834SJeeja KP 1151c9b1e834SJeeja KP return 0; 1152c9b1e834SJeeja KP } 11539939a9c3SJeeja KP 11542004432fSJeeja KP /* 11552004432fSJeeja KP * Reset the pipeline by sending set pipe state IPC this will reset the DMA 11562004432fSJeeja KP * from the DSP side 11572004432fSJeeja KP */ 11582004432fSJeeja KP int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 11592004432fSJeeja KP { 11602004432fSJeeja KP int ret; 11612004432fSJeeja KP 11622004432fSJeeja KP /* If pipe was not created in FW, do not try to pause or delete */ 11632004432fSJeeja KP if (pipe->state < SKL_PIPE_PAUSED) 11642004432fSJeeja KP return 0; 11652004432fSJeeja KP 11662004432fSJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_RESET); 11672004432fSJeeja KP if (ret < 0) { 11682004432fSJeeja KP dev_dbg(ctx->dev, "Failed to reset pipe ret=%d\n", ret); 11692004432fSJeeja KP return ret; 11702004432fSJeeja KP } 11712004432fSJeeja KP 11722004432fSJeeja KP pipe->state = SKL_PIPE_RESET; 11732004432fSJeeja KP 11742004432fSJeeja KP return 0; 11752004432fSJeeja KP } 11762004432fSJeeja KP 11779939a9c3SJeeja KP /* Algo parameter set helper function */ 11789939a9c3SJeeja KP int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, 11799939a9c3SJeeja KP u32 param_id, struct skl_module_cfg *mcfg) 11809939a9c3SJeeja KP { 11819939a9c3SJeeja KP struct skl_ipc_large_config_msg msg; 11829939a9c3SJeeja KP 11839939a9c3SJeeja KP msg.module_id = mcfg->id.module_id; 1184ef2a352cSDharageswari R msg.instance_id = mcfg->id.pvt_id; 11859939a9c3SJeeja KP msg.param_data_size = size; 11869939a9c3SJeeja KP msg.large_param_id = param_id; 11879939a9c3SJeeja KP 11889939a9c3SJeeja KP return skl_ipc_set_large_config(&ctx->ipc, &msg, params); 11899939a9c3SJeeja KP } 11907d9f2911SOmair M Abdullah 11917d9f2911SOmair M Abdullah int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, 11927d9f2911SOmair M Abdullah u32 param_id, struct skl_module_cfg *mcfg) 11937d9f2911SOmair M Abdullah { 11947d9f2911SOmair M Abdullah struct skl_ipc_large_config_msg msg; 11957d9f2911SOmair M Abdullah 11967d9f2911SOmair M Abdullah msg.module_id = mcfg->id.module_id; 1197ef2a352cSDharageswari R msg.instance_id = mcfg->id.pvt_id; 11987d9f2911SOmair M Abdullah msg.param_data_size = size; 11997d9f2911SOmair M Abdullah msg.large_param_id = param_id; 12007d9f2911SOmair M Abdullah 12017d9f2911SOmair M Abdullah return skl_ipc_get_large_config(&ctx->ipc, &msg, params); 12027d9f2911SOmair M Abdullah } 1203