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, 206bc23ca35SJeeja KP .cleanup = skl_sst_dsp_cleanup 207bc23ca35SJeeja KP }, 20892eb4f62SJeeja KP { 209451dfb5fSVinod Koul .id = 0x9d71, 210451dfb5fSVinod Koul .loader_ops = skl_get_loader_ops, 211451dfb5fSVinod Koul .init = skl_sst_dsp_init, 212451dfb5fSVinod Koul .cleanup = skl_sst_dsp_cleanup 213451dfb5fSVinod Koul }, 214451dfb5fSVinod Koul { 21592eb4f62SJeeja KP .id = 0x5a98, 21692eb4f62SJeeja KP .loader_ops = bxt_get_loader_ops, 21792eb4f62SJeeja KP .init = bxt_sst_dsp_init, 21892eb4f62SJeeja KP .cleanup = bxt_sst_dsp_cleanup 21992eb4f62SJeeja KP }, 220bc23ca35SJeeja KP }; 221bc23ca35SJeeja KP 22273a67581SVinod Koul const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id) 223bc23ca35SJeeja KP { 224bc23ca35SJeeja KP int i; 225bc23ca35SJeeja KP 226bc23ca35SJeeja KP for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) { 227bc23ca35SJeeja KP if (dsp_ops[i].id == pci_id) 22873a67581SVinod Koul return &dsp_ops[i]; 229bc23ca35SJeeja KP } 230bc23ca35SJeeja KP 23173a67581SVinod Koul return NULL; 232bc23ca35SJeeja KP } 233bc23ca35SJeeja KP 234d255b095SJeeja KP int skl_init_dsp(struct skl *skl) 235d255b095SJeeja KP { 236d255b095SJeeja KP void __iomem *mmio_base; 237d255b095SJeeja KP struct hdac_ext_bus *ebus = &skl->ebus; 238d255b095SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 239d255b095SJeeja KP struct skl_dsp_loader_ops loader_ops; 240bc23ca35SJeeja KP int irq = bus->irq; 24173a67581SVinod Koul const struct skl_dsp_ops *ops; 24273a67581SVinod Koul int ret; 243d255b095SJeeja KP 244d255b095SJeeja KP /* enable ppcap interrupt */ 245d255b095SJeeja KP snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 246d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 247d255b095SJeeja KP 248d255b095SJeeja KP /* read the BAR of the ADSP MMIO */ 249d255b095SJeeja KP mmio_base = pci_ioremap_bar(skl->pci, 4); 250d255b095SJeeja KP if (mmio_base == NULL) { 251d255b095SJeeja KP dev_err(bus->dev, "ioremap error\n"); 252d255b095SJeeja KP return -ENXIO; 253d255b095SJeeja KP } 254d255b095SJeeja KP 25573a67581SVinod Koul ops = skl_get_dsp_ops(skl->pci->device); 25673a67581SVinod Koul if (!ops) 25773a67581SVinod Koul return -EIO; 258bc23ca35SJeeja KP 25973a67581SVinod Koul loader_ops = ops->loader_ops(); 26073a67581SVinod Koul ret = ops->init(bus->dev, mmio_base, irq, 26173a67581SVinod Koul skl->fw_name, loader_ops, 26273a67581SVinod Koul &skl->skl_sst); 263bc23ca35SJeeja KP 2642ac454ffSJeeja KP if (ret < 0) 2652ac454ffSJeeja KP return ret; 2662ac454ffSJeeja KP 2674e10996bSJeeja KP skl_dsp_enable_notification(skl->skl_sst, false); 268d255b095SJeeja KP dev_dbg(bus->dev, "dsp registration status=%d\n", ret); 269d255b095SJeeja KP 270d255b095SJeeja KP return ret; 271d255b095SJeeja KP } 272d255b095SJeeja KP 273bc23ca35SJeeja KP int skl_free_dsp(struct skl *skl) 274d255b095SJeeja KP { 275d255b095SJeeja KP struct hdac_ext_bus *ebus = &skl->ebus; 276d255b095SJeeja KP struct hdac_bus *bus = ebus_to_hbus(ebus); 277d255b095SJeeja KP struct skl_sst *ctx = skl->skl_sst; 27873a67581SVinod Koul const struct skl_dsp_ops *ops; 279d255b095SJeeja KP 280d255b095SJeeja KP /* disable ppcap interrupt */ 281d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 282d255b095SJeeja KP 28373a67581SVinod Koul ops = skl_get_dsp_ops(skl->pci->device); 28473a67581SVinod Koul if (!ops) 285bc23ca35SJeeja KP return -EIO; 286bc23ca35SJeeja KP 28773a67581SVinod Koul ops->cleanup(bus->dev, ctx); 288bc23ca35SJeeja KP 289d255b095SJeeja KP if (ctx->dsp->addr.lpe) 290d255b095SJeeja KP iounmap(ctx->dsp->addr.lpe); 291bc23ca35SJeeja KP 292bc23ca35SJeeja KP return 0; 293d255b095SJeeja KP } 294d255b095SJeeja KP 295d255b095SJeeja KP int skl_suspend_dsp(struct skl *skl) 296d255b095SJeeja KP { 297d255b095SJeeja KP struct skl_sst *ctx = skl->skl_sst; 298d255b095SJeeja KP int ret; 299d255b095SJeeja KP 300d255b095SJeeja KP /* if ppcap is not supported return 0 */ 301d255b095SJeeja KP if (!skl->ebus.ppcap) 302d255b095SJeeja KP return 0; 303d255b095SJeeja KP 304d255b095SJeeja KP ret = skl_dsp_sleep(ctx->dsp); 305d255b095SJeeja KP if (ret < 0) 306d255b095SJeeja KP return ret; 307d255b095SJeeja KP 308d255b095SJeeja KP /* disable ppcap interrupt */ 309d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 310d255b095SJeeja KP snd_hdac_ext_bus_ppcap_enable(&skl->ebus, false); 311d255b095SJeeja KP 312d255b095SJeeja KP return 0; 313d255b095SJeeja KP } 314d255b095SJeeja KP 315d255b095SJeeja KP int skl_resume_dsp(struct skl *skl) 316d255b095SJeeja KP { 317d255b095SJeeja KP struct skl_sst *ctx = skl->skl_sst; 3184e10996bSJeeja KP int ret; 319d255b095SJeeja KP 320d255b095SJeeja KP /* if ppcap is not supported return 0 */ 321d255b095SJeeja KP if (!skl->ebus.ppcap) 322d255b095SJeeja KP return 0; 323d255b095SJeeja KP 324d255b095SJeeja KP /* enable ppcap interrupt */ 325d255b095SJeeja KP snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 326d255b095SJeeja KP snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true); 327d255b095SJeeja KP 3284e10996bSJeeja KP ret = skl_dsp_wake(ctx->dsp); 3294e10996bSJeeja KP if (ret < 0) 3304e10996bSJeeja KP return ret; 3314e10996bSJeeja KP 3324e10996bSJeeja KP skl_dsp_enable_notification(skl->skl_sst, false); 3334e10996bSJeeja KP return ret; 334d255b095SJeeja KP } 33523db472bSJeeja KP 33623db472bSJeeja KP enum skl_bitdepth skl_get_bit_depth(int params) 33723db472bSJeeja KP { 33823db472bSJeeja KP switch (params) { 33923db472bSJeeja KP case 8: 34023db472bSJeeja KP return SKL_DEPTH_8BIT; 34123db472bSJeeja KP 34223db472bSJeeja KP case 16: 34323db472bSJeeja KP return SKL_DEPTH_16BIT; 34423db472bSJeeja KP 34523db472bSJeeja KP case 24: 34623db472bSJeeja KP return SKL_DEPTH_24BIT; 34723db472bSJeeja KP 34823db472bSJeeja KP case 32: 34923db472bSJeeja KP return SKL_DEPTH_32BIT; 35023db472bSJeeja KP 35123db472bSJeeja KP default: 35223db472bSJeeja KP return SKL_DEPTH_INVALID; 35323db472bSJeeja KP 35423db472bSJeeja KP } 35523db472bSJeeja KP } 35623db472bSJeeja KP 35723db472bSJeeja KP /* 35823db472bSJeeja KP * Each module in DSP expects a base module configuration, which consists of 35923db472bSJeeja KP * PCM format information, which we calculate in driver and resource values 36023db472bSJeeja KP * which are read from widget information passed through topology binary 36123db472bSJeeja KP * This is send when we create a module with INIT_INSTANCE IPC msg 36223db472bSJeeja KP */ 36323db472bSJeeja KP static void skl_set_base_module_format(struct skl_sst *ctx, 36423db472bSJeeja KP struct skl_module_cfg *mconfig, 36523db472bSJeeja KP struct skl_base_cfg *base_cfg) 36623db472bSJeeja KP { 3674cd9899fSHardik T Shah struct skl_module_fmt *format = &mconfig->in_fmt[0]; 36823db472bSJeeja KP 36923db472bSJeeja KP base_cfg->audio_fmt.number_of_channels = (u8)format->channels; 37023db472bSJeeja KP 37123db472bSJeeja KP base_cfg->audio_fmt.s_freq = format->s_freq; 37223db472bSJeeja KP base_cfg->audio_fmt.bit_depth = format->bit_depth; 37323db472bSJeeja KP base_cfg->audio_fmt.valid_bit_depth = format->valid_bit_depth; 37423db472bSJeeja KP base_cfg->audio_fmt.ch_cfg = format->ch_cfg; 37523db472bSJeeja KP 37623db472bSJeeja KP dev_dbg(ctx->dev, "bit_depth=%x valid_bd=%x ch_config=%x\n", 37723db472bSJeeja KP format->bit_depth, format->valid_bit_depth, 37823db472bSJeeja KP format->ch_cfg); 37923db472bSJeeja KP 3803e81f1a3SJeeja KP base_cfg->audio_fmt.channel_map = format->ch_map; 38123db472bSJeeja KP 3823e81f1a3SJeeja KP base_cfg->audio_fmt.interleaving = format->interleaving_style; 38323db472bSJeeja KP 38423db472bSJeeja KP base_cfg->cps = mconfig->mcps; 38523db472bSJeeja KP base_cfg->ibs = mconfig->ibs; 38623db472bSJeeja KP base_cfg->obs = mconfig->obs; 387b18c458dSJeeja KP base_cfg->is_pages = mconfig->mem_pages; 38823db472bSJeeja KP } 38923db472bSJeeja KP 39023db472bSJeeja KP /* 39123db472bSJeeja KP * Copies copier capabilities into copier module and updates copier module 39223db472bSJeeja KP * config size. 39323db472bSJeeja KP */ 39423db472bSJeeja KP static void skl_copy_copier_caps(struct skl_module_cfg *mconfig, 39523db472bSJeeja KP struct skl_cpr_cfg *cpr_mconfig) 39623db472bSJeeja KP { 39723db472bSJeeja KP if (mconfig->formats_config.caps_size == 0) 39823db472bSJeeja KP return; 39923db472bSJeeja KP 40023db472bSJeeja KP memcpy(cpr_mconfig->gtw_cfg.config_data, 40123db472bSJeeja KP mconfig->formats_config.caps, 40223db472bSJeeja KP mconfig->formats_config.caps_size); 40323db472bSJeeja KP 40423db472bSJeeja KP cpr_mconfig->gtw_cfg.config_length = 40523db472bSJeeja KP (mconfig->formats_config.caps_size) / 4; 40623db472bSJeeja KP } 40723db472bSJeeja KP 408bfa764acSJeeja KP #define SKL_NON_GATEWAY_CPR_NODE_ID 0xFFFFFFFF 40923db472bSJeeja KP /* 41023db472bSJeeja KP * Calculate the gatewat settings required for copier module, type of 41123db472bSJeeja KP * gateway and index of gateway to use 41223db472bSJeeja KP */ 4134fdf810fSDharageswari.R static u32 skl_get_node_id(struct skl_sst *ctx, 4144fdf810fSDharageswari.R struct skl_module_cfg *mconfig) 41523db472bSJeeja KP { 41623db472bSJeeja KP union skl_connector_node_id node_id = {0}; 417d7b18813SJeeja KP union skl_ssp_dma_node ssp_node = {0}; 41823db472bSJeeja KP struct skl_pipe_params *params = mconfig->pipe->p_params; 41923db472bSJeeja KP 42023db472bSJeeja KP switch (mconfig->dev_type) { 42123db472bSJeeja KP case SKL_DEVICE_BT: 42223db472bSJeeja KP node_id.node.dma_type = 42323db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 42423db472bSJeeja KP SKL_DMA_I2S_LINK_OUTPUT_CLASS : 42523db472bSJeeja KP SKL_DMA_I2S_LINK_INPUT_CLASS; 42623db472bSJeeja KP node_id.node.vindex = params->host_dma_id + 42723db472bSJeeja KP (mconfig->vbus_id << 3); 42823db472bSJeeja KP break; 42923db472bSJeeja KP 43023db472bSJeeja KP case SKL_DEVICE_I2S: 43123db472bSJeeja KP node_id.node.dma_type = 43223db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 43323db472bSJeeja KP SKL_DMA_I2S_LINK_OUTPUT_CLASS : 43423db472bSJeeja KP SKL_DMA_I2S_LINK_INPUT_CLASS; 435d7b18813SJeeja KP ssp_node.dma_node.time_slot_index = mconfig->time_slot; 436d7b18813SJeeja KP ssp_node.dma_node.i2s_instance = mconfig->vbus_id; 437d7b18813SJeeja KP node_id.node.vindex = ssp_node.val; 43823db472bSJeeja KP break; 43923db472bSJeeja KP 44023db472bSJeeja KP case SKL_DEVICE_DMIC: 44123db472bSJeeja KP node_id.node.dma_type = SKL_DMA_DMIC_LINK_INPUT_CLASS; 44223db472bSJeeja KP node_id.node.vindex = mconfig->vbus_id + 44323db472bSJeeja KP (mconfig->time_slot); 44423db472bSJeeja KP break; 44523db472bSJeeja KP 44623db472bSJeeja KP case SKL_DEVICE_HDALINK: 44723db472bSJeeja KP node_id.node.dma_type = 44823db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 44923db472bSJeeja KP SKL_DMA_HDA_LINK_OUTPUT_CLASS : 45023db472bSJeeja KP SKL_DMA_HDA_LINK_INPUT_CLASS; 45123db472bSJeeja KP node_id.node.vindex = params->link_dma_id; 45223db472bSJeeja KP break; 45323db472bSJeeja KP 454bfa764acSJeeja KP case SKL_DEVICE_HDAHOST: 45523db472bSJeeja KP node_id.node.dma_type = 45623db472bSJeeja KP (SKL_CONN_SOURCE == mconfig->hw_conn_type) ? 45723db472bSJeeja KP SKL_DMA_HDA_HOST_OUTPUT_CLASS : 45823db472bSJeeja KP SKL_DMA_HDA_HOST_INPUT_CLASS; 45923db472bSJeeja KP node_id.node.vindex = params->host_dma_id; 46023db472bSJeeja KP break; 461bfa764acSJeeja KP 462bfa764acSJeeja KP default: 4634fdf810fSDharageswari.R node_id.val = 0xFFFFFFFF; 4644fdf810fSDharageswari.R break; 4654fdf810fSDharageswari.R } 4664fdf810fSDharageswari.R 4674fdf810fSDharageswari.R return node_id.val; 4684fdf810fSDharageswari.R } 4694fdf810fSDharageswari.R 4704fdf810fSDharageswari.R static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, 4714fdf810fSDharageswari.R struct skl_module_cfg *mconfig, 4724fdf810fSDharageswari.R struct skl_cpr_cfg *cpr_mconfig) 4734fdf810fSDharageswari.R { 4744fdf810fSDharageswari.R cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig); 4754fdf810fSDharageswari.R 4764fdf810fSDharageswari.R if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) { 477bfa764acSJeeja KP cpr_mconfig->cpr_feature_mask = 0; 478bfa764acSJeeja KP return; 47923db472bSJeeja KP } 48023db472bSJeeja KP 48123db472bSJeeja KP if (SKL_CONN_SOURCE == mconfig->hw_conn_type) 48223db472bSJeeja KP cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs; 48323db472bSJeeja KP else 48423db472bSJeeja KP cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->ibs; 48523db472bSJeeja KP 48623db472bSJeeja KP cpr_mconfig->cpr_feature_mask = 0; 48723db472bSJeeja KP cpr_mconfig->gtw_cfg.config_length = 0; 48823db472bSJeeja KP 48923db472bSJeeja KP skl_copy_copier_caps(mconfig, cpr_mconfig); 49023db472bSJeeja KP } 49123db472bSJeeja KP 492c115fa5eSDharageswari.R #define DMA_CONTROL_ID 5 493c115fa5eSDharageswari.R 494c115fa5eSDharageswari.R int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig) 495c115fa5eSDharageswari.R { 496c115fa5eSDharageswari.R struct skl_dma_control *dma_ctrl; 497c115fa5eSDharageswari.R struct skl_i2s_config_blob config_blob; 498c115fa5eSDharageswari.R struct skl_ipc_large_config_msg msg = {0}; 499c115fa5eSDharageswari.R int err = 0; 500c115fa5eSDharageswari.R 501c115fa5eSDharageswari.R 502c115fa5eSDharageswari.R /* 503c115fa5eSDharageswari.R * if blob size is same as capablity size, then no dma control 504c115fa5eSDharageswari.R * present so return 505c115fa5eSDharageswari.R */ 506c115fa5eSDharageswari.R if (mconfig->formats_config.caps_size == sizeof(config_blob)) 507c115fa5eSDharageswari.R return 0; 508c115fa5eSDharageswari.R 509c115fa5eSDharageswari.R msg.large_param_id = DMA_CONTROL_ID; 510c115fa5eSDharageswari.R msg.param_data_size = sizeof(struct skl_dma_control) + 511c115fa5eSDharageswari.R mconfig->formats_config.caps_size; 512c115fa5eSDharageswari.R 513c115fa5eSDharageswari.R dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL); 514c115fa5eSDharageswari.R if (dma_ctrl == NULL) 515c115fa5eSDharageswari.R return -ENOMEM; 516c115fa5eSDharageswari.R 517c115fa5eSDharageswari.R dma_ctrl->node_id = skl_get_node_id(ctx, mconfig); 518c115fa5eSDharageswari.R 519c115fa5eSDharageswari.R /* size in dwords */ 520c115fa5eSDharageswari.R dma_ctrl->config_length = sizeof(config_blob) / 4; 521c115fa5eSDharageswari.R 522c115fa5eSDharageswari.R memcpy(dma_ctrl->config_data, mconfig->formats_config.caps, 523c115fa5eSDharageswari.R mconfig->formats_config.caps_size); 524c115fa5eSDharageswari.R 525c115fa5eSDharageswari.R err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl); 526c115fa5eSDharageswari.R 527c115fa5eSDharageswari.R kfree(dma_ctrl); 528c115fa5eSDharageswari.R 529c115fa5eSDharageswari.R return err; 530c115fa5eSDharageswari.R } 531c115fa5eSDharageswari.R 53223db472bSJeeja KP static void skl_setup_out_format(struct skl_sst *ctx, 53323db472bSJeeja KP struct skl_module_cfg *mconfig, 53423db472bSJeeja KP struct skl_audio_data_format *out_fmt) 53523db472bSJeeja KP { 5364cd9899fSHardik T Shah struct skl_module_fmt *format = &mconfig->out_fmt[0]; 53723db472bSJeeja KP 53823db472bSJeeja KP out_fmt->number_of_channels = (u8)format->channels; 53923db472bSJeeja KP out_fmt->s_freq = format->s_freq; 54023db472bSJeeja KP out_fmt->bit_depth = format->bit_depth; 54123db472bSJeeja KP out_fmt->valid_bit_depth = format->valid_bit_depth; 54223db472bSJeeja KP out_fmt->ch_cfg = format->ch_cfg; 54323db472bSJeeja KP 5443e81f1a3SJeeja KP out_fmt->channel_map = format->ch_map; 5453e81f1a3SJeeja KP out_fmt->interleaving = format->interleaving_style; 5463e81f1a3SJeeja KP out_fmt->sample_type = format->sample_type; 54723db472bSJeeja KP 54823db472bSJeeja KP dev_dbg(ctx->dev, "copier out format chan=%d fre=%d bitdepth=%d\n", 54923db472bSJeeja KP out_fmt->number_of_channels, format->s_freq, format->bit_depth); 55023db472bSJeeja KP } 55123db472bSJeeja KP 55223db472bSJeeja KP /* 553a0ffe48bSHardik T Shah * DSP needs SRC module for frequency conversion, SRC takes base module 554a0ffe48bSHardik T Shah * configuration and the target frequency as extra parameter passed as src 555a0ffe48bSHardik T Shah * config 556a0ffe48bSHardik T Shah */ 557a0ffe48bSHardik T Shah static void skl_set_src_format(struct skl_sst *ctx, 558a0ffe48bSHardik T Shah struct skl_module_cfg *mconfig, 559a0ffe48bSHardik T Shah struct skl_src_module_cfg *src_mconfig) 560a0ffe48bSHardik T Shah { 5614cd9899fSHardik T Shah struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; 562a0ffe48bSHardik T Shah 563a0ffe48bSHardik T Shah skl_set_base_module_format(ctx, mconfig, 564a0ffe48bSHardik T Shah (struct skl_base_cfg *)src_mconfig); 565a0ffe48bSHardik T Shah 566a0ffe48bSHardik T Shah src_mconfig->src_cfg = fmt->s_freq; 567a0ffe48bSHardik T Shah } 568a0ffe48bSHardik T Shah 569a0ffe48bSHardik T Shah /* 570a0ffe48bSHardik T Shah * DSP needs updown module to do channel conversion. updown module take base 571a0ffe48bSHardik T Shah * module configuration and channel configuration 572a0ffe48bSHardik T Shah * It also take coefficients and now we have defaults applied here 573a0ffe48bSHardik T Shah */ 574a0ffe48bSHardik T Shah static void skl_set_updown_mixer_format(struct skl_sst *ctx, 575a0ffe48bSHardik T Shah struct skl_module_cfg *mconfig, 576a0ffe48bSHardik T Shah struct skl_up_down_mixer_cfg *mixer_mconfig) 577a0ffe48bSHardik T Shah { 5784cd9899fSHardik T Shah struct skl_module_fmt *fmt = &mconfig->out_fmt[0]; 579a0ffe48bSHardik T Shah int i = 0; 580a0ffe48bSHardik T Shah 581a0ffe48bSHardik T Shah skl_set_base_module_format(ctx, mconfig, 582a0ffe48bSHardik T Shah (struct skl_base_cfg *)mixer_mconfig); 583a0ffe48bSHardik T Shah mixer_mconfig->out_ch_cfg = fmt->ch_cfg; 584a0ffe48bSHardik T Shah 585a0ffe48bSHardik T Shah /* Select F/W default coefficient */ 586a0ffe48bSHardik T Shah mixer_mconfig->coeff_sel = 0x0; 587a0ffe48bSHardik T Shah 588a0ffe48bSHardik T Shah /* User coeff, don't care since we are selecting F/W defaults */ 589a0ffe48bSHardik T Shah for (i = 0; i < UP_DOWN_MIXER_MAX_COEFF; i++) 590a0ffe48bSHardik T Shah mixer_mconfig->coeff[i] = 0xDEADBEEF; 591a0ffe48bSHardik T Shah } 592a0ffe48bSHardik T Shah 593a0ffe48bSHardik T Shah /* 59423db472bSJeeja KP * 'copier' is DSP internal module which copies data from Host DMA (HDA host 59523db472bSJeeja KP * dma) or link (hda link, SSP, PDM) 59623db472bSJeeja KP * Here we calculate the copier module parameters, like PCM format, output 59723db472bSJeeja KP * format, gateway settings 59823db472bSJeeja KP * copier_module_config is sent as input buffer with INIT_INSTANCE IPC msg 59923db472bSJeeja KP */ 60023db472bSJeeja KP static void skl_set_copier_format(struct skl_sst *ctx, 60123db472bSJeeja KP struct skl_module_cfg *mconfig, 60223db472bSJeeja KP struct skl_cpr_cfg *cpr_mconfig) 60323db472bSJeeja KP { 60423db472bSJeeja KP struct skl_audio_data_format *out_fmt = &cpr_mconfig->out_fmt; 60523db472bSJeeja KP struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)cpr_mconfig; 60623db472bSJeeja KP 60723db472bSJeeja KP skl_set_base_module_format(ctx, mconfig, base_cfg); 60823db472bSJeeja KP 60923db472bSJeeja KP skl_setup_out_format(ctx, mconfig, out_fmt); 61023db472bSJeeja KP skl_setup_cpr_gateway_cfg(ctx, mconfig, cpr_mconfig); 61123db472bSJeeja KP } 61223db472bSJeeja KP 613399b210bSJeeja KP /* 614399b210bSJeeja KP * Algo module are DSP pre processing modules. Algo module take base module 615399b210bSJeeja KP * configuration and params 616399b210bSJeeja KP */ 617399b210bSJeeja KP 618399b210bSJeeja KP static void skl_set_algo_format(struct skl_sst *ctx, 619399b210bSJeeja KP struct skl_module_cfg *mconfig, 620399b210bSJeeja KP struct skl_algo_cfg *algo_mcfg) 621399b210bSJeeja KP { 622399b210bSJeeja KP struct skl_base_cfg *base_cfg = (struct skl_base_cfg *)algo_mcfg; 623399b210bSJeeja KP 624399b210bSJeeja KP skl_set_base_module_format(ctx, mconfig, base_cfg); 625399b210bSJeeja KP 626399b210bSJeeja KP if (mconfig->formats_config.caps_size == 0) 627399b210bSJeeja KP return; 628399b210bSJeeja KP 629399b210bSJeeja KP memcpy(algo_mcfg->params, 630399b210bSJeeja KP mconfig->formats_config.caps, 631399b210bSJeeja KP mconfig->formats_config.caps_size); 632399b210bSJeeja KP 633399b210bSJeeja KP } 634399b210bSJeeja KP 635fd18110fSDharageswari R /* 636fd18110fSDharageswari R * Mic select module allows selecting one or many input channels, thus 637fd18110fSDharageswari R * acting as a demux. 638fd18110fSDharageswari R * 639fd18110fSDharageswari R * Mic select module take base module configuration and out-format 640fd18110fSDharageswari R * configuration 641fd18110fSDharageswari R */ 642fd18110fSDharageswari R static void skl_set_base_outfmt_format(struct skl_sst *ctx, 643fd18110fSDharageswari R struct skl_module_cfg *mconfig, 644fd18110fSDharageswari R struct skl_base_outfmt_cfg *base_outfmt_mcfg) 645fd18110fSDharageswari R { 646fd18110fSDharageswari R struct skl_audio_data_format *out_fmt = &base_outfmt_mcfg->out_fmt; 647fd18110fSDharageswari R struct skl_base_cfg *base_cfg = 648fd18110fSDharageswari R (struct skl_base_cfg *)base_outfmt_mcfg; 649fd18110fSDharageswari R 650fd18110fSDharageswari R skl_set_base_module_format(ctx, mconfig, base_cfg); 651fd18110fSDharageswari R skl_setup_out_format(ctx, mconfig, out_fmt); 652fd18110fSDharageswari R } 653fd18110fSDharageswari R 65423db472bSJeeja KP static u16 skl_get_module_param_size(struct skl_sst *ctx, 65523db472bSJeeja KP struct skl_module_cfg *mconfig) 65623db472bSJeeja KP { 65723db472bSJeeja KP u16 param_size; 65823db472bSJeeja KP 65923db472bSJeeja KP switch (mconfig->m_type) { 66023db472bSJeeja KP case SKL_MODULE_TYPE_COPIER: 66123db472bSJeeja KP param_size = sizeof(struct skl_cpr_cfg); 66223db472bSJeeja KP param_size += mconfig->formats_config.caps_size; 66323db472bSJeeja KP return param_size; 66423db472bSJeeja KP 665a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_SRCINT: 666a0ffe48bSHardik T Shah return sizeof(struct skl_src_module_cfg); 667a0ffe48bSHardik T Shah 668a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_UPDWMIX: 669a0ffe48bSHardik T Shah return sizeof(struct skl_up_down_mixer_cfg); 670a0ffe48bSHardik T Shah 671399b210bSJeeja KP case SKL_MODULE_TYPE_ALGO: 672399b210bSJeeja KP param_size = sizeof(struct skl_base_cfg); 673399b210bSJeeja KP param_size += mconfig->formats_config.caps_size; 674399b210bSJeeja KP return param_size; 675399b210bSJeeja KP 676fd18110fSDharageswari R case SKL_MODULE_TYPE_BASE_OUTFMT: 677fd18110fSDharageswari R return sizeof(struct skl_base_outfmt_cfg); 678fd18110fSDharageswari R 67923db472bSJeeja KP default: 68023db472bSJeeja KP /* 68123db472bSJeeja KP * return only base cfg when no specific module type is 68223db472bSJeeja KP * specified 68323db472bSJeeja KP */ 68423db472bSJeeja KP return sizeof(struct skl_base_cfg); 68523db472bSJeeja KP } 68623db472bSJeeja KP 68723db472bSJeeja KP return 0; 68823db472bSJeeja KP } 68923db472bSJeeja KP 69023db472bSJeeja KP /* 691a0ffe48bSHardik T Shah * DSP firmware supports various modules like copier, SRC, updown etc. 692a0ffe48bSHardik T Shah * These modules required various parameters to be calculated and sent for 693a0ffe48bSHardik T Shah * the module initialization to DSP. By default a generic module needs only 694a0ffe48bSHardik T Shah * base module format configuration 69523db472bSJeeja KP */ 696a0ffe48bSHardik T Shah 69723db472bSJeeja KP static int skl_set_module_format(struct skl_sst *ctx, 69823db472bSJeeja KP struct skl_module_cfg *module_config, 69923db472bSJeeja KP u16 *module_config_size, 70023db472bSJeeja KP void **param_data) 70123db472bSJeeja KP { 70223db472bSJeeja KP u16 param_size; 70323db472bSJeeja KP 70423db472bSJeeja KP param_size = skl_get_module_param_size(ctx, module_config); 70523db472bSJeeja KP 70623db472bSJeeja KP *param_data = kzalloc(param_size, GFP_KERNEL); 70723db472bSJeeja KP if (NULL == *param_data) 70823db472bSJeeja KP return -ENOMEM; 70923db472bSJeeja KP 71023db472bSJeeja KP *module_config_size = param_size; 71123db472bSJeeja KP 71223db472bSJeeja KP switch (module_config->m_type) { 71323db472bSJeeja KP case SKL_MODULE_TYPE_COPIER: 71423db472bSJeeja KP skl_set_copier_format(ctx, module_config, *param_data); 71523db472bSJeeja KP break; 71623db472bSJeeja KP 717a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_SRCINT: 718a0ffe48bSHardik T Shah skl_set_src_format(ctx, module_config, *param_data); 719a0ffe48bSHardik T Shah break; 720a0ffe48bSHardik T Shah 721a0ffe48bSHardik T Shah case SKL_MODULE_TYPE_UPDWMIX: 722a0ffe48bSHardik T Shah skl_set_updown_mixer_format(ctx, module_config, *param_data); 723a0ffe48bSHardik T Shah break; 724a0ffe48bSHardik T Shah 725399b210bSJeeja KP case SKL_MODULE_TYPE_ALGO: 726399b210bSJeeja KP skl_set_algo_format(ctx, module_config, *param_data); 727399b210bSJeeja KP break; 728399b210bSJeeja KP 729fd18110fSDharageswari R case SKL_MODULE_TYPE_BASE_OUTFMT: 730fd18110fSDharageswari R skl_set_base_outfmt_format(ctx, module_config, *param_data); 731fd18110fSDharageswari R break; 732fd18110fSDharageswari R 73323db472bSJeeja KP default: 73423db472bSJeeja KP skl_set_base_module_format(ctx, module_config, *param_data); 73523db472bSJeeja KP break; 73623db472bSJeeja KP 73723db472bSJeeja KP } 73823db472bSJeeja KP 73923db472bSJeeja KP dev_dbg(ctx->dev, "Module type=%d config size: %d bytes\n", 74023db472bSJeeja KP module_config->id.module_id, param_size); 74191c18325SVedang Patel print_hex_dump_debug("Module params:", DUMP_PREFIX_OFFSET, 8, 4, 74223db472bSJeeja KP *param_data, param_size, false); 74323db472bSJeeja KP return 0; 74423db472bSJeeja KP } 74523db472bSJeeja KP 74623db472bSJeeja KP static int skl_get_queue_index(struct skl_module_pin *mpin, 74723db472bSJeeja KP struct skl_module_inst_id id, int max) 74823db472bSJeeja KP { 74923db472bSJeeja KP int i; 75023db472bSJeeja KP 75123db472bSJeeja KP for (i = 0; i < max; i++) { 75223db472bSJeeja KP if (mpin[i].id.module_id == id.module_id && 75323db472bSJeeja KP mpin[i].id.instance_id == id.instance_id) 75423db472bSJeeja KP return i; 75523db472bSJeeja KP } 75623db472bSJeeja KP 75723db472bSJeeja KP return -EINVAL; 75823db472bSJeeja KP } 75923db472bSJeeja KP 76023db472bSJeeja KP /* 76123db472bSJeeja KP * Allocates queue for each module. 76223db472bSJeeja KP * if dynamic, the pin_index is allocated 0 to max_pin. 76323db472bSJeeja KP * In static, the pin_index is fixed based on module_id and instance id 76423db472bSJeeja KP */ 76523db472bSJeeja KP static int skl_alloc_queue(struct skl_module_pin *mpin, 7664f745708SJeeja KP struct skl_module_cfg *tgt_cfg, int max) 76723db472bSJeeja KP { 76823db472bSJeeja KP int i; 7694f745708SJeeja KP struct skl_module_inst_id id = tgt_cfg->id; 77023db472bSJeeja KP /* 77123db472bSJeeja KP * if pin in dynamic, find first free pin 77223db472bSJeeja KP * otherwise find match module and instance id pin as topology will 77323db472bSJeeja KP * ensure a unique pin is assigned to this so no need to 77423db472bSJeeja KP * allocate/free 77523db472bSJeeja KP */ 77623db472bSJeeja KP for (i = 0; i < max; i++) { 77723db472bSJeeja KP if (mpin[i].is_dynamic) { 7784f745708SJeeja KP if (!mpin[i].in_use && 7794f745708SJeeja KP mpin[i].pin_state == SKL_PIN_UNBIND) { 7804f745708SJeeja KP 78123db472bSJeeja KP mpin[i].in_use = true; 78223db472bSJeeja KP mpin[i].id.module_id = id.module_id; 78323db472bSJeeja KP mpin[i].id.instance_id = id.instance_id; 7844f745708SJeeja KP mpin[i].tgt_mcfg = tgt_cfg; 78523db472bSJeeja KP return i; 78623db472bSJeeja KP } 78723db472bSJeeja KP } else { 78823db472bSJeeja KP if (mpin[i].id.module_id == id.module_id && 7894f745708SJeeja KP mpin[i].id.instance_id == id.instance_id && 7904f745708SJeeja KP mpin[i].pin_state == SKL_PIN_UNBIND) { 7914f745708SJeeja KP 7924f745708SJeeja KP mpin[i].tgt_mcfg = tgt_cfg; 79323db472bSJeeja KP return i; 79423db472bSJeeja KP } 79523db472bSJeeja KP } 7964f745708SJeeja KP } 79723db472bSJeeja KP 79823db472bSJeeja KP return -EINVAL; 79923db472bSJeeja KP } 80023db472bSJeeja KP 80123db472bSJeeja KP static void skl_free_queue(struct skl_module_pin *mpin, int q_index) 80223db472bSJeeja KP { 80323db472bSJeeja KP if (mpin[q_index].is_dynamic) { 80423db472bSJeeja KP mpin[q_index].in_use = false; 80523db472bSJeeja KP mpin[q_index].id.module_id = 0; 80623db472bSJeeja KP mpin[q_index].id.instance_id = 0; 80723db472bSJeeja KP } 8084f745708SJeeja KP mpin[q_index].pin_state = SKL_PIN_UNBIND; 8094f745708SJeeja KP mpin[q_index].tgt_mcfg = NULL; 8104f745708SJeeja KP } 8114f745708SJeeja KP 8124f745708SJeeja KP /* Module state will be set to unint, if all the out pin state is UNBIND */ 8134f745708SJeeja KP 8144f745708SJeeja KP static void skl_clear_module_state(struct skl_module_pin *mpin, int max, 8154f745708SJeeja KP struct skl_module_cfg *mcfg) 8164f745708SJeeja KP { 8174f745708SJeeja KP int i; 8184f745708SJeeja KP bool found = false; 8194f745708SJeeja KP 8204f745708SJeeja KP for (i = 0; i < max; i++) { 8214f745708SJeeja KP if (mpin[i].pin_state == SKL_PIN_UNBIND) 8224f745708SJeeja KP continue; 8234f745708SJeeja KP found = true; 8244f745708SJeeja KP break; 8254f745708SJeeja KP } 8264f745708SJeeja KP 8274f745708SJeeja KP if (!found) 8284f745708SJeeja KP mcfg->m_state = SKL_MODULE_UNINIT; 8294f745708SJeeja KP return; 83023db472bSJeeja KP } 831beb73b26SJeeja KP 832beb73b26SJeeja KP /* 833beb73b26SJeeja KP * A module needs to be instanataited in DSP. A mdoule is present in a 834beb73b26SJeeja KP * collection of module referred as a PIPE. 835beb73b26SJeeja KP * We first calculate the module format, based on module type and then 836beb73b26SJeeja KP * invoke the DSP by sending IPC INIT_INSTANCE using ipc helper 837beb73b26SJeeja KP */ 838beb73b26SJeeja KP int skl_init_module(struct skl_sst *ctx, 8399939a9c3SJeeja KP struct skl_module_cfg *mconfig) 840beb73b26SJeeja KP { 841beb73b26SJeeja KP u16 module_config_size = 0; 842beb73b26SJeeja KP void *param_data = NULL; 843beb73b26SJeeja KP int ret; 844beb73b26SJeeja KP struct skl_ipc_init_instance_msg msg; 845beb73b26SJeeja KP 846beb73b26SJeeja KP dev_dbg(ctx->dev, "%s: module_id = %d instance=%d\n", __func__, 847beb73b26SJeeja KP mconfig->id.module_id, mconfig->id.instance_id); 848beb73b26SJeeja KP 849beb73b26SJeeja KP if (mconfig->pipe->state != SKL_PIPE_CREATED) { 850beb73b26SJeeja KP dev_err(ctx->dev, "Pipe not created state= %d pipe_id= %d\n", 851beb73b26SJeeja KP mconfig->pipe->state, mconfig->pipe->ppl_id); 852beb73b26SJeeja KP return -EIO; 853beb73b26SJeeja KP } 854beb73b26SJeeja KP 855beb73b26SJeeja KP ret = skl_set_module_format(ctx, mconfig, 856beb73b26SJeeja KP &module_config_size, ¶m_data); 857beb73b26SJeeja KP if (ret < 0) { 858beb73b26SJeeja KP dev_err(ctx->dev, "Failed to set module format ret=%d\n", ret); 859beb73b26SJeeja KP return ret; 860beb73b26SJeeja KP } 861beb73b26SJeeja KP 862beb73b26SJeeja KP msg.module_id = mconfig->id.module_id; 863beb73b26SJeeja KP msg.instance_id = mconfig->id.instance_id; 864beb73b26SJeeja KP msg.ppl_instance_id = mconfig->pipe->ppl_id; 865beb73b26SJeeja KP msg.param_data_size = module_config_size; 866beb73b26SJeeja KP msg.core_id = mconfig->core_id; 867beb73b26SJeeja KP 868beb73b26SJeeja KP ret = skl_ipc_init_instance(&ctx->ipc, &msg, param_data); 869beb73b26SJeeja KP if (ret < 0) { 870beb73b26SJeeja KP dev_err(ctx->dev, "Failed to init instance ret=%d\n", ret); 871beb73b26SJeeja KP kfree(param_data); 872beb73b26SJeeja KP return ret; 873beb73b26SJeeja KP } 874beb73b26SJeeja KP mconfig->m_state = SKL_MODULE_INIT_DONE; 87576222d6dSMousumi Jana kfree(param_data); 876beb73b26SJeeja KP return ret; 877beb73b26SJeeja KP } 878beb73b26SJeeja KP 879beb73b26SJeeja KP static void skl_dump_bind_info(struct skl_sst *ctx, struct skl_module_cfg 880beb73b26SJeeja KP *src_module, struct skl_module_cfg *dst_module) 881beb73b26SJeeja KP { 882beb73b26SJeeja KP dev_dbg(ctx->dev, "%s: src module_id = %d src_instance=%d\n", 883beb73b26SJeeja KP __func__, src_module->id.module_id, src_module->id.instance_id); 884beb73b26SJeeja KP dev_dbg(ctx->dev, "%s: dst_module=%d dst_instacne=%d\n", __func__, 885beb73b26SJeeja KP dst_module->id.module_id, dst_module->id.instance_id); 886beb73b26SJeeja KP 887beb73b26SJeeja KP dev_dbg(ctx->dev, "src_module state = %d dst module state = %d\n", 888beb73b26SJeeja KP src_module->m_state, dst_module->m_state); 889beb73b26SJeeja KP } 890beb73b26SJeeja KP 891beb73b26SJeeja KP /* 892beb73b26SJeeja KP * On module freeup, we need to unbind the module with modules 893beb73b26SJeeja KP * it is already bind. 894beb73b26SJeeja KP * Find the pin allocated and unbind then using bind_unbind IPC 895beb73b26SJeeja KP */ 896beb73b26SJeeja KP int skl_unbind_modules(struct skl_sst *ctx, 897beb73b26SJeeja KP struct skl_module_cfg *src_mcfg, 898beb73b26SJeeja KP struct skl_module_cfg *dst_mcfg) 899beb73b26SJeeja KP { 900beb73b26SJeeja KP int ret; 901beb73b26SJeeja KP struct skl_ipc_bind_unbind_msg msg; 902beb73b26SJeeja KP struct skl_module_inst_id src_id = src_mcfg->id; 903beb73b26SJeeja KP struct skl_module_inst_id dst_id = dst_mcfg->id; 904beb73b26SJeeja KP int in_max = dst_mcfg->max_in_queue; 905beb73b26SJeeja KP int out_max = src_mcfg->max_out_queue; 9064f745708SJeeja KP int src_index, dst_index, src_pin_state, dst_pin_state; 907beb73b26SJeeja KP 908beb73b26SJeeja KP skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 909beb73b26SJeeja KP 910beb73b26SJeeja KP /* get src queue index */ 911beb73b26SJeeja KP src_index = skl_get_queue_index(src_mcfg->m_out_pin, dst_id, out_max); 912beb73b26SJeeja KP if (src_index < 0) 9139cf3049eSJeeja KP return 0; 914beb73b26SJeeja KP 9154f745708SJeeja KP msg.src_queue = src_index; 916beb73b26SJeeja KP 917beb73b26SJeeja KP /* get dst queue index */ 918beb73b26SJeeja KP dst_index = skl_get_queue_index(dst_mcfg->m_in_pin, src_id, in_max); 919beb73b26SJeeja KP if (dst_index < 0) 9209cf3049eSJeeja KP return 0; 921beb73b26SJeeja KP 9224f745708SJeeja KP msg.dst_queue = dst_index; 9234f745708SJeeja KP 9244f745708SJeeja KP src_pin_state = src_mcfg->m_out_pin[src_index].pin_state; 9254f745708SJeeja KP dst_pin_state = dst_mcfg->m_in_pin[dst_index].pin_state; 9264f745708SJeeja KP 9274f745708SJeeja KP if (src_pin_state != SKL_PIN_BIND_DONE || 9284f745708SJeeja KP dst_pin_state != SKL_PIN_BIND_DONE) 9294f745708SJeeja KP return 0; 930beb73b26SJeeja KP 931beb73b26SJeeja KP msg.module_id = src_mcfg->id.module_id; 932beb73b26SJeeja KP msg.instance_id = src_mcfg->id.instance_id; 933beb73b26SJeeja KP msg.dst_module_id = dst_mcfg->id.module_id; 934beb73b26SJeeja KP msg.dst_instance_id = dst_mcfg->id.instance_id; 935beb73b26SJeeja KP msg.bind = false; 936beb73b26SJeeja KP 937beb73b26SJeeja KP ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 938beb73b26SJeeja KP if (!ret) { 939beb73b26SJeeja KP /* free queue only if unbind is success */ 940beb73b26SJeeja KP skl_free_queue(src_mcfg->m_out_pin, src_index); 941beb73b26SJeeja KP skl_free_queue(dst_mcfg->m_in_pin, dst_index); 9424f745708SJeeja KP 9434f745708SJeeja KP /* 9444f745708SJeeja KP * check only if src module bind state, bind is 9454f745708SJeeja KP * always from src -> sink 9464f745708SJeeja KP */ 9474f745708SJeeja KP skl_clear_module_state(src_mcfg->m_out_pin, out_max, src_mcfg); 948beb73b26SJeeja KP } 949beb73b26SJeeja KP 950beb73b26SJeeja KP return ret; 951beb73b26SJeeja KP } 952beb73b26SJeeja KP 953beb73b26SJeeja KP /* 954beb73b26SJeeja KP * Once a module is instantiated it need to be 'bind' with other modules in 955beb73b26SJeeja KP * the pipeline. For binding we need to find the module pins which are bind 956beb73b26SJeeja KP * together 957beb73b26SJeeja KP * This function finds the pins and then sends bund_unbind IPC message to 958beb73b26SJeeja KP * DSP using IPC helper 959beb73b26SJeeja KP */ 960beb73b26SJeeja KP int skl_bind_modules(struct skl_sst *ctx, 961beb73b26SJeeja KP struct skl_module_cfg *src_mcfg, 962beb73b26SJeeja KP struct skl_module_cfg *dst_mcfg) 963beb73b26SJeeja KP { 964beb73b26SJeeja KP int ret; 965beb73b26SJeeja KP struct skl_ipc_bind_unbind_msg msg; 966beb73b26SJeeja KP int in_max = dst_mcfg->max_in_queue; 967beb73b26SJeeja KP int out_max = src_mcfg->max_out_queue; 968beb73b26SJeeja KP int src_index, dst_index; 969beb73b26SJeeja KP 970beb73b26SJeeja KP skl_dump_bind_info(ctx, src_mcfg, dst_mcfg); 971beb73b26SJeeja KP 9720c684c48SJeeja KP if (src_mcfg->m_state < SKL_MODULE_INIT_DONE || 973beb73b26SJeeja KP dst_mcfg->m_state < SKL_MODULE_INIT_DONE) 974beb73b26SJeeja KP return 0; 975beb73b26SJeeja KP 9764f745708SJeeja KP src_index = skl_alloc_queue(src_mcfg->m_out_pin, dst_mcfg, out_max); 977beb73b26SJeeja KP if (src_index < 0) 978beb73b26SJeeja KP return -EINVAL; 979beb73b26SJeeja KP 9804f745708SJeeja KP msg.src_queue = src_index; 9814f745708SJeeja KP dst_index = skl_alloc_queue(dst_mcfg->m_in_pin, src_mcfg, in_max); 982beb73b26SJeeja KP if (dst_index < 0) { 983beb73b26SJeeja KP skl_free_queue(src_mcfg->m_out_pin, src_index); 984beb73b26SJeeja KP return -EINVAL; 985beb73b26SJeeja KP } 986beb73b26SJeeja KP 9874f745708SJeeja KP msg.dst_queue = dst_index; 988beb73b26SJeeja KP 989beb73b26SJeeja KP dev_dbg(ctx->dev, "src queue = %d dst queue =%d\n", 990beb73b26SJeeja KP msg.src_queue, msg.dst_queue); 991beb73b26SJeeja KP 992beb73b26SJeeja KP msg.module_id = src_mcfg->id.module_id; 993beb73b26SJeeja KP msg.instance_id = src_mcfg->id.instance_id; 994beb73b26SJeeja KP msg.dst_module_id = dst_mcfg->id.module_id; 995beb73b26SJeeja KP msg.dst_instance_id = dst_mcfg->id.instance_id; 996beb73b26SJeeja KP msg.bind = true; 997beb73b26SJeeja KP 998beb73b26SJeeja KP ret = skl_ipc_bind_unbind(&ctx->ipc, &msg); 999beb73b26SJeeja KP 1000beb73b26SJeeja KP if (!ret) { 1001beb73b26SJeeja KP src_mcfg->m_state = SKL_MODULE_BIND_DONE; 10024f745708SJeeja KP src_mcfg->m_out_pin[src_index].pin_state = SKL_PIN_BIND_DONE; 10034f745708SJeeja KP dst_mcfg->m_in_pin[dst_index].pin_state = SKL_PIN_BIND_DONE; 1004beb73b26SJeeja KP } else { 1005beb73b26SJeeja KP /* error case , if IPC fails, clear the queue index */ 1006beb73b26SJeeja KP skl_free_queue(src_mcfg->m_out_pin, src_index); 1007beb73b26SJeeja KP skl_free_queue(dst_mcfg->m_in_pin, dst_index); 1008beb73b26SJeeja KP } 1009beb73b26SJeeja KP 1010beb73b26SJeeja KP return ret; 1011beb73b26SJeeja KP } 1012c9b1e834SJeeja KP 1013c9b1e834SJeeja KP static int skl_set_pipe_state(struct skl_sst *ctx, struct skl_pipe *pipe, 1014c9b1e834SJeeja KP enum skl_ipc_pipeline_state state) 1015c9b1e834SJeeja KP { 1016c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe_satate = %d\n", __func__, state); 1017c9b1e834SJeeja KP 1018c9b1e834SJeeja KP return skl_ipc_set_pipeline_state(&ctx->ipc, pipe->ppl_id, state); 1019c9b1e834SJeeja KP } 1020c9b1e834SJeeja KP 1021c9b1e834SJeeja KP /* 1022c9b1e834SJeeja KP * A pipeline is a collection of modules. Before a module in instantiated a 1023c9b1e834SJeeja KP * pipeline needs to be created for it. 1024c9b1e834SJeeja KP * This function creates pipeline, by sending create pipeline IPC messages 1025c9b1e834SJeeja KP * to FW 1026c9b1e834SJeeja KP */ 1027c9b1e834SJeeja KP int skl_create_pipeline(struct skl_sst *ctx, struct skl_pipe *pipe) 1028c9b1e834SJeeja KP { 1029c9b1e834SJeeja KP int ret; 1030c9b1e834SJeeja KP 1031c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe_id = %d\n", __func__, pipe->ppl_id); 1032c9b1e834SJeeja KP 1033c9b1e834SJeeja KP ret = skl_ipc_create_pipeline(&ctx->ipc, pipe->memory_pages, 1034c9b1e834SJeeja KP pipe->pipe_priority, pipe->ppl_id); 1035c9b1e834SJeeja KP if (ret < 0) { 1036c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to create pipeline\n"); 1037c9b1e834SJeeja KP return ret; 1038c9b1e834SJeeja KP } 1039c9b1e834SJeeja KP 1040c9b1e834SJeeja KP pipe->state = SKL_PIPE_CREATED; 1041c9b1e834SJeeja KP 1042c9b1e834SJeeja KP return 0; 1043c9b1e834SJeeja KP } 1044c9b1e834SJeeja KP 1045c9b1e834SJeeja KP /* 1046c9b1e834SJeeja KP * A pipeline needs to be deleted on cleanup. If a pipeline is running, then 1047c9b1e834SJeeja KP * pause the pipeline first and then delete it 1048c9b1e834SJeeja KP * The pipe delete is done by sending delete pipeline IPC. DSP will stop the 1049c9b1e834SJeeja KP * DMA engines and releases resources 1050c9b1e834SJeeja KP */ 1051c9b1e834SJeeja KP int skl_delete_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1052c9b1e834SJeeja KP { 1053c9b1e834SJeeja KP int ret; 1054c9b1e834SJeeja KP 1055c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1056c9b1e834SJeeja KP 10571ae7ca04SDharageswari R /* If pipe is started, do stop the pipe in FW. */ 1058c9b1e834SJeeja KP if (pipe->state > SKL_PIPE_STARTED) { 1059c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1060c9b1e834SJeeja KP if (ret < 0) { 1061c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to stop pipeline\n"); 1062c9b1e834SJeeja KP return ret; 1063c9b1e834SJeeja KP } 1064c9b1e834SJeeja KP 1065c9b1e834SJeeja KP pipe->state = SKL_PIPE_PAUSED; 10661ae7ca04SDharageswari R } 10671ae7ca04SDharageswari R 1068c9b1e834SJeeja KP /* If pipe was not created in FW, do not try to delete it */ 1069c9b1e834SJeeja KP if (pipe->state < SKL_PIPE_CREATED) 1070c9b1e834SJeeja KP return 0; 1071c9b1e834SJeeja KP 1072c9b1e834SJeeja KP ret = skl_ipc_delete_pipeline(&ctx->ipc, pipe->ppl_id); 10731ae7ca04SDharageswari R if (ret < 0) { 1074c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to delete pipeline\n"); 10751ae7ca04SDharageswari R return ret; 10761ae7ca04SDharageswari R } 1077d2c7db85SJeeja KP 1078d2c7db85SJeeja KP pipe->state = SKL_PIPE_INVALID; 1079c9b1e834SJeeja KP 1080c9b1e834SJeeja KP return ret; 1081c9b1e834SJeeja KP } 1082c9b1e834SJeeja KP 1083c9b1e834SJeeja KP /* 1084c9b1e834SJeeja KP * A pipeline is also a scheduling entity in DSP which can be run, stopped 1085c9b1e834SJeeja KP * For processing data the pipe need to be run by sending IPC set pipe state 1086c9b1e834SJeeja KP * to DSP 1087c9b1e834SJeeja KP */ 1088c9b1e834SJeeja KP int skl_run_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1089c9b1e834SJeeja KP { 1090c9b1e834SJeeja KP int ret; 1091c9b1e834SJeeja KP 1092c9b1e834SJeeja KP dev_dbg(ctx->dev, "%s: pipe = %d\n", __func__, pipe->ppl_id); 1093c9b1e834SJeeja KP 1094c9b1e834SJeeja KP /* If pipe was not created in FW, do not try to pause or delete */ 1095c9b1e834SJeeja KP if (pipe->state < SKL_PIPE_CREATED) 1096c9b1e834SJeeja KP return 0; 1097c9b1e834SJeeja KP 1098c9b1e834SJeeja KP /* Pipe has to be paused before it is started */ 1099c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1100c9b1e834SJeeja KP if (ret < 0) { 1101c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to pause pipe\n"); 1102c9b1e834SJeeja KP return ret; 1103c9b1e834SJeeja KP } 1104c9b1e834SJeeja KP 1105c9b1e834SJeeja KP pipe->state = SKL_PIPE_PAUSED; 1106c9b1e834SJeeja KP 1107c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_RUNNING); 1108c9b1e834SJeeja KP if (ret < 0) { 1109c9b1e834SJeeja KP dev_err(ctx->dev, "Failed to start pipe\n"); 1110c9b1e834SJeeja KP return ret; 1111c9b1e834SJeeja KP } 1112c9b1e834SJeeja KP 1113c9b1e834SJeeja KP pipe->state = SKL_PIPE_STARTED; 1114c9b1e834SJeeja KP 1115c9b1e834SJeeja KP return 0; 1116c9b1e834SJeeja KP } 1117c9b1e834SJeeja KP 1118c9b1e834SJeeja KP /* 1119c9b1e834SJeeja KP * Stop the pipeline by sending set pipe state IPC 1120c9b1e834SJeeja KP * DSP doesnt implement stop so we always send pause message 1121c9b1e834SJeeja KP */ 1122c9b1e834SJeeja KP int skl_stop_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 1123c9b1e834SJeeja KP { 1124c9b1e834SJeeja KP int ret; 1125c9b1e834SJeeja KP 1126c9b1e834SJeeja KP dev_dbg(ctx->dev, "In %s pipe=%d\n", __func__, pipe->ppl_id); 1127c9b1e834SJeeja KP 1128c9b1e834SJeeja KP /* If pipe was not created in FW, do not try to pause or delete */ 1129c9b1e834SJeeja KP if (pipe->state < SKL_PIPE_PAUSED) 1130c9b1e834SJeeja KP return 0; 1131c9b1e834SJeeja KP 1132c9b1e834SJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_PAUSED); 1133c9b1e834SJeeja KP if (ret < 0) { 1134c9b1e834SJeeja KP dev_dbg(ctx->dev, "Failed to stop pipe\n"); 1135c9b1e834SJeeja KP return ret; 1136c9b1e834SJeeja KP } 1137c9b1e834SJeeja KP 1138353f72aaSJeeja KP pipe->state = SKL_PIPE_PAUSED; 1139c9b1e834SJeeja KP 1140c9b1e834SJeeja KP return 0; 1141c9b1e834SJeeja KP } 11429939a9c3SJeeja KP 11432004432fSJeeja KP /* 11442004432fSJeeja KP * Reset the pipeline by sending set pipe state IPC this will reset the DMA 11452004432fSJeeja KP * from the DSP side 11462004432fSJeeja KP */ 11472004432fSJeeja KP int skl_reset_pipe(struct skl_sst *ctx, struct skl_pipe *pipe) 11482004432fSJeeja KP { 11492004432fSJeeja KP int ret; 11502004432fSJeeja KP 11512004432fSJeeja KP /* If pipe was not created in FW, do not try to pause or delete */ 11522004432fSJeeja KP if (pipe->state < SKL_PIPE_PAUSED) 11532004432fSJeeja KP return 0; 11542004432fSJeeja KP 11552004432fSJeeja KP ret = skl_set_pipe_state(ctx, pipe, PPL_RESET); 11562004432fSJeeja KP if (ret < 0) { 11572004432fSJeeja KP dev_dbg(ctx->dev, "Failed to reset pipe ret=%d\n", ret); 11582004432fSJeeja KP return ret; 11592004432fSJeeja KP } 11602004432fSJeeja KP 11612004432fSJeeja KP pipe->state = SKL_PIPE_RESET; 11622004432fSJeeja KP 11632004432fSJeeja KP return 0; 11642004432fSJeeja KP } 11652004432fSJeeja KP 11669939a9c3SJeeja KP /* Algo parameter set helper function */ 11679939a9c3SJeeja KP int skl_set_module_params(struct skl_sst *ctx, u32 *params, int size, 11689939a9c3SJeeja KP u32 param_id, struct skl_module_cfg *mcfg) 11699939a9c3SJeeja KP { 11709939a9c3SJeeja KP struct skl_ipc_large_config_msg msg; 11719939a9c3SJeeja KP 11729939a9c3SJeeja KP msg.module_id = mcfg->id.module_id; 11739939a9c3SJeeja KP msg.instance_id = mcfg->id.instance_id; 11749939a9c3SJeeja KP msg.param_data_size = size; 11759939a9c3SJeeja KP msg.large_param_id = param_id; 11769939a9c3SJeeja KP 11779939a9c3SJeeja KP return skl_ipc_set_large_config(&ctx->ipc, &msg, params); 11789939a9c3SJeeja KP } 11797d9f2911SOmair M Abdullah 11807d9f2911SOmair M Abdullah int skl_get_module_params(struct skl_sst *ctx, u32 *params, int size, 11817d9f2911SOmair M Abdullah u32 param_id, struct skl_module_cfg *mcfg) 11827d9f2911SOmair M Abdullah { 11837d9f2911SOmair M Abdullah struct skl_ipc_large_config_msg msg; 11847d9f2911SOmair M Abdullah 11857d9f2911SOmair M Abdullah msg.module_id = mcfg->id.module_id; 11867d9f2911SOmair M Abdullah msg.instance_id = mcfg->id.instance_id; 11877d9f2911SOmair M Abdullah msg.param_data_size = size; 11887d9f2911SOmair M Abdullah msg.large_param_id = param_id; 11897d9f2911SOmair M Abdullah 11907d9f2911SOmair M Abdullah return skl_ipc_get_large_config(&ctx->ipc, &msg, params); 11917d9f2911SOmair M Abdullah } 1192