/*
 * Intel SST Firmware Loader
 *
 * Copyright (C) 2013, Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/firmware.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/pci.h>
#include <linux/acpi.h>

/* supported DMA engine drivers */
#include <linux/dma/dw.h>

#include <asm/page.h>
#include <asm/pgtable.h>

#include "sst-dsp.h"
#include "sst-dsp-priv.h"

#define SST_DMA_RESOURCES	2
#define SST_DSP_DMA_MAX_BURST	0x3
#define SST_HSW_BLOCK_ANY	0xffffffff

#define SST_HSW_MASK_DMA_ADDR_DSP 0xfff00000

struct sst_dma {
	struct sst_dsp *sst;

	struct dw_dma_chip *chip;

	struct dma_async_tx_descriptor *desc;
	struct dma_chan *ch;
};

static inline void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes)
{
	u32 tmp = 0;
	int i, m, n;
	const u8 *src_byte = src;

	m = bytes / 4;
	n = bytes % 4;

	/* __iowrite32_copy use 32bit size values so divide by 4 */
	__iowrite32_copy((void *)dest, src, m);

	if (n) {
		for (i = 0; i < n; i++)
			tmp |= (u32)*(src_byte + m * 4 + i) << (i * 8);
		__iowrite32_copy((void *)(dest + m * 4), &tmp, 1);
	}

}

static void sst_dma_transfer_complete(void *arg)
{
	struct sst_dsp *sst = (struct sst_dsp *)arg;

	dev_dbg(sst->dev, "DMA: callback\n");
}

static int sst_dsp_dma_copy(struct sst_dsp *sst, dma_addr_t dest_addr,
	dma_addr_t src_addr, size_t size)
{
	struct dma_async_tx_descriptor *desc;
	struct sst_dma *dma = sst->dma;

	if (dma->ch == NULL) {
		dev_err(sst->dev, "error: no DMA channel\n");
		return -ENODEV;
	}

	dev_dbg(sst->dev, "DMA: src: 0x%lx dest 0x%lx size %zu\n",
		(unsigned long)src_addr, (unsigned long)dest_addr, size);

	desc = dma->ch->device->device_prep_dma_memcpy(dma->ch, dest_addr,
		src_addr, size, DMA_CTRL_ACK);
	if (!desc){
		dev_err(sst->dev, "error: dma prep memcpy failed\n");
		return -EINVAL;
	}

	desc->callback = sst_dma_transfer_complete;
	desc->callback_param = sst;

	desc->tx_submit(desc);
	dma_wait_for_async_tx(desc);

	return 0;
}

/* copy to DSP */
int sst_dsp_dma_copyto(struct sst_dsp *sst, dma_addr_t dest_addr,
	dma_addr_t src_addr, size_t size)
{
	return sst_dsp_dma_copy(sst, dest_addr | SST_HSW_MASK_DMA_ADDR_DSP,
			src_addr, size);
}
EXPORT_SYMBOL_GPL(sst_dsp_dma_copyto);

/* copy from DSP */
int sst_dsp_dma_copyfrom(struct sst_dsp *sst, dma_addr_t dest_addr,
	dma_addr_t src_addr, size_t size)
{
	return sst_dsp_dma_copy(sst, dest_addr,
		src_addr | SST_HSW_MASK_DMA_ADDR_DSP, size);
}
EXPORT_SYMBOL_GPL(sst_dsp_dma_copyfrom);

/* remove module from memory - callers hold locks */
static void block_list_remove(struct sst_dsp *dsp,
	struct list_head *block_list)
{
	struct sst_mem_block *block, *tmp;
	int err;

	/* disable each block  */
	list_for_each_entry(block, block_list, module_list) {

		if (block->ops && block->ops->disable) {
			err = block->ops->disable(block);
			if (err < 0)
				dev_err(dsp->dev,
					"error: cant disable block %d:%d\n",
					block->type, block->index);
		}
	}

	/* mark each block as free */
	list_for_each_entry_safe(block, tmp, block_list, module_list) {
		list_del(&block->module_list);
		list_move(&block->list, &dsp->free_block_list);
		dev_dbg(dsp->dev, "block freed %d:%d at offset 0x%x\n",
			block->type, block->index, block->offset);
	}
}

/* prepare the memory block to receive data from host - callers hold locks */
static int block_list_prepare(struct sst_dsp *dsp,
	struct list_head *block_list)
{
	struct sst_mem_block *block;
	int ret = 0;

	/* enable each block so that's it'e ready for data */
	list_for_each_entry(block, block_list, module_list) {

		if (block->ops && block->ops->enable && !block->users) {
			ret = block->ops->enable(block);
			if (ret < 0) {
				dev_err(dsp->dev,
					"error: cant disable block %d:%d\n",
					block->type, block->index);
				goto err;
			}
		}
	}
	return ret;

err:
	list_for_each_entry(block, block_list, module_list) {
		if (block->ops && block->ops->disable)
			block->ops->disable(block);
	}
	return ret;
}

static struct dw_dma_chip *dw_probe(struct device *dev, struct resource *mem,
	int irq)
{
	struct dw_dma_chip *chip;
	int err;

	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return ERR_PTR(-ENOMEM);

	chip->irq = irq;
	chip->regs = devm_ioremap_resource(dev, mem);
	if (IS_ERR(chip->regs))
		return ERR_CAST(chip->regs);

	err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(31));
	if (err)
		return ERR_PTR(err);

	chip->dev = dev;

	err = dw_dma_probe(chip);
	if (err)
		return ERR_PTR(err);

	return chip;
}

static void dw_remove(struct dw_dma_chip *chip)
{
	dw_dma_remove(chip);
}

static bool dma_chan_filter(struct dma_chan *chan, void *param)
{
	struct sst_dsp *dsp = (struct sst_dsp *)param;

	return chan->device->dev == dsp->dma_dev;
}

int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id)
{
	struct sst_dma *dma = dsp->dma;
	struct dma_slave_config slave;
	dma_cap_mask_t mask;
	int ret;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	dma_cap_set(DMA_MEMCPY, mask);

	dma->ch = dma_request_channel(mask, dma_chan_filter, dsp);
	if (dma->ch == NULL) {
		dev_err(dsp->dev, "error: DMA request channel failed\n");
		return -EIO;
	}

	memset(&slave, 0, sizeof(slave));
	slave.direction = DMA_MEM_TO_DEV;
	slave.src_addr_width =
		slave.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	slave.src_maxburst = slave.dst_maxburst = SST_DSP_DMA_MAX_BURST;

	ret = dmaengine_slave_config(dma->ch, &slave);
	if (ret) {
		dev_err(dsp->dev, "error: unable to set DMA slave config %d\n",
			ret);
		dma_release_channel(dma->ch);
		dma->ch = NULL;
	}

	return ret;
}
EXPORT_SYMBOL_GPL(sst_dsp_dma_get_channel);

void sst_dsp_dma_put_channel(struct sst_dsp *dsp)
{
	struct sst_dma *dma = dsp->dma;

	if (!dma->ch)
		return;

	dma_release_channel(dma->ch);
	dma->ch = NULL;
}
EXPORT_SYMBOL_GPL(sst_dsp_dma_put_channel);

int sst_dma_new(struct sst_dsp *sst)
{
	struct sst_pdata *sst_pdata = sst->pdata;
	struct sst_dma *dma;
	struct resource mem;
	int ret = 0;

	if (sst->pdata->resindex_dma_base == -1)
		/* DMA is not used, return and squelsh error messages */
		return 0;

	/* configure the correct platform data for whatever DMA engine
	* is attached to the ADSP IP. */
	switch (sst->pdata->dma_engine) {
	case SST_DMA_TYPE_DW:
		break;
	default:
		dev_err(sst->dev, "error: invalid DMA engine %d\n",
			sst->pdata->dma_engine);
		return -EINVAL;
	}

	dma = devm_kzalloc(sst->dev, sizeof(struct sst_dma), GFP_KERNEL);
	if (!dma)
		return -ENOMEM;

	dma->sst = sst;

	memset(&mem, 0, sizeof(mem));

	mem.start = sst->addr.lpe_base + sst_pdata->dma_base;
	mem.end   = sst->addr.lpe_base + sst_pdata->dma_base + sst_pdata->dma_size - 1;
	mem.flags = IORESOURCE_MEM;

	/* now register DMA engine device */
	dma->chip = dw_probe(sst->dma_dev, &mem, sst_pdata->irq);
	if (IS_ERR(dma->chip)) {
		dev_err(sst->dev, "error: DMA device register failed\n");
		ret = PTR_ERR(dma->chip);
		goto err_dma_dev;
	}

	sst->dma = dma;
	sst->fw_use_dma = true;
	return 0;

err_dma_dev:
	devm_kfree(sst->dev, dma);
	return ret;
}
EXPORT_SYMBOL(sst_dma_new);

void sst_dma_free(struct sst_dma *dma)
{

	if (dma == NULL)
		return;

	if (dma->ch)
		dma_release_channel(dma->ch);

	if (dma->chip)
		dw_remove(dma->chip);

}
EXPORT_SYMBOL(sst_dma_free);

/* create new generic firmware object */
struct sst_fw *sst_fw_new(struct sst_dsp *dsp, 
	const struct firmware *fw, void *private)
{
	struct sst_fw *sst_fw;
	int err;

	if (!dsp->ops->parse_fw)
		return NULL;

	sst_fw = kzalloc(sizeof(*sst_fw), GFP_KERNEL);
	if (sst_fw == NULL)
		return NULL;

	sst_fw->dsp = dsp;
	sst_fw->private = private;
	sst_fw->size = fw->size;

	/* allocate DMA buffer to store FW data */
	sst_fw->dma_buf = dma_alloc_coherent(dsp->dma_dev, sst_fw->size,
				&sst_fw->dmable_fw_paddr, GFP_DMA | GFP_KERNEL);
	if (!sst_fw->dma_buf) {
		dev_err(dsp->dev, "error: DMA alloc failed\n");
		kfree(sst_fw);
		return NULL;
	}

	/* copy FW data to DMA-able memory */
	memcpy((void *)sst_fw->dma_buf, (void *)fw->data, fw->size);

	if (dsp->fw_use_dma) {
		err = sst_dsp_dma_get_channel(dsp, 0);
		if (err < 0)
			goto chan_err;
	}

	/* call core specific FW paser to load FW data into DSP */
	err = dsp->ops->parse_fw(sst_fw);
	if (err < 0) {
		dev_err(dsp->dev, "error: parse fw failed %d\n", err);
		goto parse_err;
	}

	if (dsp->fw_use_dma)
		sst_dsp_dma_put_channel(dsp);

	mutex_lock(&dsp->mutex);
	list_add(&sst_fw->list, &dsp->fw_list);
	mutex_unlock(&dsp->mutex);

	return sst_fw;

parse_err:
	if (dsp->fw_use_dma)
		sst_dsp_dma_put_channel(dsp);
chan_err:
	dma_free_coherent(dsp->dma_dev, sst_fw->size,
				sst_fw->dma_buf,
				sst_fw->dmable_fw_paddr);
	sst_fw->dma_buf = NULL;
	kfree(sst_fw);
	return NULL;
}
EXPORT_SYMBOL_GPL(sst_fw_new);

int sst_fw_reload(struct sst_fw *sst_fw)
{
	struct sst_dsp *dsp = sst_fw->dsp;
	int ret;

	dev_dbg(dsp->dev, "reloading firmware\n");

	/* call core specific FW paser to load FW data into DSP */
	ret = dsp->ops->parse_fw(sst_fw);
	if (ret < 0)
		dev_err(dsp->dev, "error: parse fw failed %d\n", ret);

	return ret;
}
EXPORT_SYMBOL_GPL(sst_fw_reload);

void sst_fw_unload(struct sst_fw *sst_fw)
{
	struct sst_dsp *dsp = sst_fw->dsp;
	struct sst_module *module, *mtmp;
	struct sst_module_runtime *runtime, *rtmp;

	dev_dbg(dsp->dev, "unloading firmware\n");

	mutex_lock(&dsp->mutex);

	/* check module by module */
	list_for_each_entry_safe(module, mtmp, &dsp->module_list, list) {
		if (module->sst_fw == sst_fw) {

			/* remove runtime modules */
			list_for_each_entry_safe(runtime, rtmp, &module->runtime_list, list) {

				block_list_remove(dsp, &runtime->block_list);
				list_del(&runtime->list);
				kfree(runtime);
			}

			/* now remove the module */
			block_list_remove(dsp, &module->block_list);
			list_del(&module->list);
			kfree(module);
		}
	}

	/* remove all scratch blocks */
	block_list_remove(dsp, &dsp->scratch_block_list);

	mutex_unlock(&dsp->mutex);
}
EXPORT_SYMBOL_GPL(sst_fw_unload);

/* free single firmware object */
void sst_fw_free(struct sst_fw *sst_fw)
{
	struct sst_dsp *dsp = sst_fw->dsp;

	mutex_lock(&dsp->mutex);
	list_del(&sst_fw->list);
	mutex_unlock(&dsp->mutex);

	if (sst_fw->dma_buf)
		dma_free_coherent(dsp->dma_dev, sst_fw->size, sst_fw->dma_buf,
			sst_fw->dmable_fw_paddr);
	kfree(sst_fw);
}
EXPORT_SYMBOL_GPL(sst_fw_free);

/* free all firmware objects */
void sst_fw_free_all(struct sst_dsp *dsp)
{
	struct sst_fw *sst_fw, *t;

	mutex_lock(&dsp->mutex);
	list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) {

		list_del(&sst_fw->list);
		dma_free_coherent(dsp->dev, sst_fw->size, sst_fw->dma_buf,
			sst_fw->dmable_fw_paddr);
		kfree(sst_fw);
	}
	mutex_unlock(&dsp->mutex);
}
EXPORT_SYMBOL_GPL(sst_fw_free_all);

/* create a new SST generic module from FW template */
struct sst_module *sst_module_new(struct sst_fw *sst_fw,
	struct sst_module_template *template, void *private)
{
	struct sst_dsp *dsp = sst_fw->dsp;
	struct sst_module *sst_module;

	sst_module = kzalloc(sizeof(*sst_module), GFP_KERNEL);
	if (sst_module == NULL)
		return NULL;

	sst_module->id = template->id;
	sst_module->dsp = dsp;
	sst_module->sst_fw = sst_fw;
	sst_module->scratch_size = template->scratch_size;
	sst_module->persistent_size = template->persistent_size;
	sst_module->entry = template->entry;
	sst_module->state = SST_MODULE_STATE_UNLOADED;

	INIT_LIST_HEAD(&sst_module->block_list);
	INIT_LIST_HEAD(&sst_module->runtime_list);

	mutex_lock(&dsp->mutex);
	list_add(&sst_module->list, &dsp->module_list);
	mutex_unlock(&dsp->mutex);

	return sst_module;
}
EXPORT_SYMBOL_GPL(sst_module_new);

/* free firmware module and remove from available list */
void sst_module_free(struct sst_module *sst_module)
{
	struct sst_dsp *dsp = sst_module->dsp;

	mutex_lock(&dsp->mutex);
	list_del(&sst_module->list);
	mutex_unlock(&dsp->mutex);

	kfree(sst_module);
}
EXPORT_SYMBOL_GPL(sst_module_free);

struct sst_module_runtime *sst_module_runtime_new(struct sst_module *module,
	int id, void *private)
{
	struct sst_dsp *dsp = module->dsp;
	struct sst_module_runtime *runtime;

	runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
	if (runtime == NULL)
		return NULL;

	runtime->id = id;
	runtime->dsp = dsp;
	runtime->module = module;
	INIT_LIST_HEAD(&runtime->block_list);

	mutex_lock(&dsp->mutex);
	list_add(&runtime->list, &module->runtime_list);
	mutex_unlock(&dsp->mutex);

	return runtime;
}
EXPORT_SYMBOL_GPL(sst_module_runtime_new);

void sst_module_runtime_free(struct sst_module_runtime *runtime)
{
	struct sst_dsp *dsp = runtime->dsp;

	mutex_lock(&dsp->mutex);
	list_del(&runtime->list);
	mutex_unlock(&dsp->mutex);

	kfree(runtime);
}
EXPORT_SYMBOL_GPL(sst_module_runtime_free);

static struct sst_mem_block *find_block(struct sst_dsp *dsp,
	struct sst_block_allocator *ba)
{
	struct sst_mem_block *block;

	list_for_each_entry(block, &dsp->free_block_list, list) {
		if (block->type == ba->type && block->offset == ba->offset)
			return block;
	}

	return NULL;
}

/* Block allocator must be on block boundary */
static int block_alloc_contiguous(struct sst_dsp *dsp,
	struct sst_block_allocator *ba, struct list_head *block_list)
{
	struct list_head tmp = LIST_HEAD_INIT(tmp);
	struct sst_mem_block *block;
	u32 block_start = SST_HSW_BLOCK_ANY;
	int size = ba->size, offset = ba->offset;

	while (ba->size > 0) {

		block = find_block(dsp, ba);
		if (!block) {
			list_splice(&tmp, &dsp->free_block_list);

			ba->size = size;
			ba->offset = offset;
			return -ENOMEM;
		}

		list_move_tail(&block->list, &tmp);
		ba->offset += block->size;
		ba->size -= block->size;
	}
	ba->size = size;
	ba->offset = offset;

	list_for_each_entry(block, &tmp, list) {

		if (block->offset < block_start)
			block_start = block->offset;

		list_add(&block->module_list, block_list);

		dev_dbg(dsp->dev, "block allocated %d:%d at offset 0x%x\n",
			block->type, block->index, block->offset);
	}

	list_splice(&tmp, &dsp->used_block_list);
	return 0;
}

/* allocate first free DSP blocks for data - callers hold locks */
static int block_alloc(struct sst_dsp *dsp, struct sst_block_allocator *ba,
	struct list_head *block_list)
{
	struct sst_mem_block *block, *tmp;
	int ret = 0;

	if (ba->size == 0)
		return 0;

	/* find first free whole blocks that can hold module */
	list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {

		/* ignore blocks with wrong type */
		if (block->type != ba->type)
			continue;

		if (ba->size > block->size)
			continue;

		ba->offset = block->offset;
		block->bytes_used = ba->size % block->size;
		list_add(&block->module_list, block_list);
		list_move(&block->list, &dsp->used_block_list);
		dev_dbg(dsp->dev, "block allocated %d:%d at offset 0x%x\n",
			block->type, block->index, block->offset);
		return 0;
	}

	/* then find free multiple blocks that can hold module */
	list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {

		/* ignore blocks with wrong type */
		if (block->type != ba->type)
			continue;

		/* do we span > 1 blocks */
		if (ba->size > block->size) {

			/* align ba to block boundary */
			ba->offset = block->offset;

			ret = block_alloc_contiguous(dsp, ba, block_list);
			if (ret == 0)
				return ret;

		}
	}

	/* not enough free block space */
	return -ENOMEM;
}

int sst_alloc_blocks(struct sst_dsp *dsp, struct sst_block_allocator *ba,
	struct list_head *block_list)
{
	int ret;

	dev_dbg(dsp->dev, "block request 0x%x bytes at offset 0x%x type %d\n",
		ba->size, ba->offset, ba->type);

	mutex_lock(&dsp->mutex);

	ret = block_alloc(dsp, ba, block_list);
	if (ret < 0) {
		dev_err(dsp->dev, "error: can't alloc blocks %d\n", ret);
		goto out;
	}

	/* prepare DSP blocks for module usage */
	ret = block_list_prepare(dsp, block_list);
	if (ret < 0)
		dev_err(dsp->dev, "error: prepare failed\n");

out:
	mutex_unlock(&dsp->mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(sst_alloc_blocks);

int sst_free_blocks(struct sst_dsp *dsp, struct list_head *block_list)
{
	mutex_lock(&dsp->mutex);
	block_list_remove(dsp, block_list);
	mutex_unlock(&dsp->mutex);
	return 0;
}
EXPORT_SYMBOL_GPL(sst_free_blocks);

/* allocate memory blocks for static module addresses - callers hold locks */
static int block_alloc_fixed(struct sst_dsp *dsp, struct sst_block_allocator *ba,
	struct list_head *block_list)
{
	struct sst_mem_block *block, *tmp;
	struct sst_block_allocator ba_tmp = *ba;
	u32 end = ba->offset + ba->size, block_end;
	int err;

	/* only IRAM/DRAM blocks are managed */
	if (ba->type != SST_MEM_IRAM && ba->type != SST_MEM_DRAM)
		return 0;

	/* are blocks already attached to this module */
	list_for_each_entry_safe(block, tmp, block_list, module_list) {

		/* ignore blocks with wrong type */
		if (block->type != ba->type)
			continue;

		block_end = block->offset + block->size;

		/* find block that holds section */
		if (ba->offset >= block->offset && end <= block_end)
			return 0;

		/* does block span more than 1 section */
		if (ba->offset >= block->offset && ba->offset < block_end) {

			/* align ba to block boundary */
			ba_tmp.size -= block_end - ba->offset;
			ba_tmp.offset = block_end;
			err = block_alloc_contiguous(dsp, &ba_tmp, block_list);
			if (err < 0)
				return -ENOMEM;

			/* module already owns blocks */
			return 0;
		}
	}

	/* find first free blocks that can hold section in free list */
	list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {
		block_end = block->offset + block->size;

		/* ignore blocks with wrong type */
		if (block->type != ba->type)
			continue;

		/* find block that holds section */
		if (ba->offset >= block->offset && end <= block_end) {

			/* add block */
			list_move(&block->list, &dsp->used_block_list);
			list_add(&block->module_list, block_list);
			dev_dbg(dsp->dev, "block allocated %d:%d at offset 0x%x\n",
				block->type, block->index, block->offset);
			return 0;
		}

		/* does block span more than 1 section */
		if (ba->offset >= block->offset && ba->offset < block_end) {

			/* add block */
			list_move(&block->list, &dsp->used_block_list);
			list_add(&block->module_list, block_list);
			/* align ba to block boundary */
			ba_tmp.size -= block_end - ba->offset;
			ba_tmp.offset = block_end;

			err = block_alloc_contiguous(dsp, &ba_tmp, block_list);
			if (err < 0)
				return -ENOMEM;

			return 0;
		}
	}

	return -ENOMEM;
}

/* Load fixed module data into DSP memory blocks */
int sst_module_alloc_blocks(struct sst_module *module)
{
	struct sst_dsp *dsp = module->dsp;
	struct sst_fw *sst_fw = module->sst_fw;
	struct sst_block_allocator ba;
	int ret;

	memset(&ba, 0, sizeof(ba));
	ba.size = module->size;
	ba.type = module->type;
	ba.offset = module->offset;

	dev_dbg(dsp->dev, "block request 0x%x bytes at offset 0x%x type %d\n",
		ba.size, ba.offset, ba.type);

	mutex_lock(&dsp->mutex);

	/* alloc blocks that includes this section */
	ret = block_alloc_fixed(dsp, &ba, &module->block_list);
	if (ret < 0) {
		dev_err(dsp->dev,
			"error: no free blocks for section at offset 0x%x size 0x%x\n",
			module->offset, module->size);
		mutex_unlock(&dsp->mutex);
		return -ENOMEM;
	}

	/* prepare DSP blocks for module copy */
	ret = block_list_prepare(dsp, &module->block_list);
	if (ret < 0) {
		dev_err(dsp->dev, "error: fw module prepare failed\n");
		goto err;
	}

	/* copy partial module data to blocks */
	if (dsp->fw_use_dma) {
		ret = sst_dsp_dma_copyto(dsp,
			dsp->addr.lpe_base + module->offset,
			sst_fw->dmable_fw_paddr + module->data_offset,
			module->size);
		if (ret < 0) {
			dev_err(dsp->dev, "error: module copy failed\n");
			goto err;
		}
	} else
		sst_memcpy32(dsp->addr.lpe + module->offset, module->data,
			module->size);

	mutex_unlock(&dsp->mutex);
	return ret;

err:
	block_list_remove(dsp, &module->block_list);
	mutex_unlock(&dsp->mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(sst_module_alloc_blocks);

/* Unload entire module from DSP memory */
int sst_module_free_blocks(struct sst_module *module)
{
	struct sst_dsp *dsp = module->dsp;

	mutex_lock(&dsp->mutex);
	block_list_remove(dsp, &module->block_list);
	mutex_unlock(&dsp->mutex);
	return 0;
}
EXPORT_SYMBOL_GPL(sst_module_free_blocks);

int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime,
	int offset)
{
	struct sst_dsp *dsp = runtime->dsp;
	struct sst_module *module = runtime->module;
	struct sst_block_allocator ba;
	int ret;

	if (module->persistent_size == 0)
		return 0;

	memset(&ba, 0, sizeof(ba));
	ba.size = module->persistent_size;
	ba.type = SST_MEM_DRAM;

	mutex_lock(&dsp->mutex);

	/* do we need to allocate at a fixed address ? */
	if (offset != 0) {

		ba.offset = offset;

		dev_dbg(dsp->dev, "persistent fixed block request 0x%x bytes type %d offset 0x%x\n",
			ba.size, ba.type, ba.offset);

		/* alloc blocks that includes this section */
		ret = block_alloc_fixed(dsp, &ba, &runtime->block_list);

	} else {
		dev_dbg(dsp->dev, "persistent block request 0x%x bytes type %d\n",
			ba.size, ba.type);

		/* alloc blocks that includes this section */
		ret = block_alloc(dsp, &ba, &runtime->block_list);
	}
	if (ret < 0) {
		dev_err(dsp->dev,
		"error: no free blocks for runtime module size 0x%x\n",
			module->persistent_size);
		mutex_unlock(&dsp->mutex);
		return -ENOMEM;
	}
	runtime->persistent_offset = ba.offset;

	/* prepare DSP blocks for module copy */
	ret = block_list_prepare(dsp, &runtime->block_list);
	if (ret < 0) {
		dev_err(dsp->dev, "error: runtime block prepare failed\n");
		goto err;
	}

	mutex_unlock(&dsp->mutex);
	return ret;

err:
	block_list_remove(dsp, &module->block_list);
	mutex_unlock(&dsp->mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(sst_module_runtime_alloc_blocks);

int sst_module_runtime_free_blocks(struct sst_module_runtime *runtime)
{
	struct sst_dsp *dsp = runtime->dsp;

	mutex_lock(&dsp->mutex);
	block_list_remove(dsp, &runtime->block_list);
	mutex_unlock(&dsp->mutex);
	return 0;
}
EXPORT_SYMBOL_GPL(sst_module_runtime_free_blocks);

int sst_module_runtime_save(struct sst_module_runtime *runtime,
	struct sst_module_runtime_context *context)
{
	struct sst_dsp *dsp = runtime->dsp;
	struct sst_module *module = runtime->module;
	int ret = 0;

	dev_dbg(dsp->dev, "saving runtime %d memory at 0x%x size 0x%x\n",
		runtime->id, runtime->persistent_offset,
		module->persistent_size);

	context->buffer = dma_alloc_coherent(dsp->dma_dev,
		module->persistent_size,
		&context->dma_buffer, GFP_DMA | GFP_KERNEL);
	if (!context->buffer) {
		dev_err(dsp->dev, "error: DMA context alloc failed\n");
		return -ENOMEM;
	}

	mutex_lock(&dsp->mutex);

	if (dsp->fw_use_dma) {

		ret = sst_dsp_dma_get_channel(dsp, 0);
		if (ret < 0)
			goto err;

		ret = sst_dsp_dma_copyfrom(dsp, context->dma_buffer,
			dsp->addr.lpe_base + runtime->persistent_offset,
			module->persistent_size);
		sst_dsp_dma_put_channel(dsp);
		if (ret < 0) {
			dev_err(dsp->dev, "error: context copy failed\n");
			goto err;
		}
	} else
		sst_memcpy32(context->buffer, dsp->addr.lpe +
			runtime->persistent_offset,
			module->persistent_size);

err:
	mutex_unlock(&dsp->mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(sst_module_runtime_save);

int sst_module_runtime_restore(struct sst_module_runtime *runtime,
	struct sst_module_runtime_context *context)
{
	struct sst_dsp *dsp = runtime->dsp;
	struct sst_module *module = runtime->module;
	int ret = 0;

	dev_dbg(dsp->dev, "restoring runtime %d memory at 0x%x size 0x%x\n",
		runtime->id, runtime->persistent_offset,
		module->persistent_size);

	mutex_lock(&dsp->mutex);

	if (!context->buffer) {
		dev_info(dsp->dev, "no context buffer need to restore!\n");
		goto err;
	}

	if (dsp->fw_use_dma) {

		ret = sst_dsp_dma_get_channel(dsp, 0);
		if (ret < 0)
			goto err;

		ret = sst_dsp_dma_copyto(dsp,
			dsp->addr.lpe_base + runtime->persistent_offset,
			context->dma_buffer, module->persistent_size);
		sst_dsp_dma_put_channel(dsp);
		if (ret < 0) {
			dev_err(dsp->dev, "error: module copy failed\n");
			goto err;
		}
	} else
		sst_memcpy32(dsp->addr.lpe + runtime->persistent_offset,
			context->buffer, module->persistent_size);

	dma_free_coherent(dsp->dma_dev, module->persistent_size,
				context->buffer, context->dma_buffer);
	context->buffer = NULL;

err:
	mutex_unlock(&dsp->mutex);
	return ret;
}
EXPORT_SYMBOL_GPL(sst_module_runtime_restore);

/* register a DSP memory block for use with FW based modules */
struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
	u32 size, enum sst_mem_type type, const struct sst_block_ops *ops,
	u32 index, void *private)
{
	struct sst_mem_block *block;

	block = kzalloc(sizeof(*block), GFP_KERNEL);
	if (block == NULL)
		return NULL;

	block->offset = offset;
	block->size = size;
	block->index = index;
	block->type = type;
	block->dsp = dsp;
	block->private = private;
	block->ops = ops;

	mutex_lock(&dsp->mutex);
	list_add(&block->list, &dsp->free_block_list);
	mutex_unlock(&dsp->mutex);

	return block;
}
EXPORT_SYMBOL_GPL(sst_mem_block_register);

/* unregister all DSP memory blocks */
void sst_mem_block_unregister_all(struct sst_dsp *dsp)
{
	struct sst_mem_block *block, *tmp;

	mutex_lock(&dsp->mutex);

	/* unregister used blocks */
	list_for_each_entry_safe(block, tmp, &dsp->used_block_list, list) {
		list_del(&block->list);
		kfree(block);
	}

	/* unregister free blocks */
	list_for_each_entry_safe(block, tmp, &dsp->free_block_list, list) {
		list_del(&block->list);
		kfree(block);
	}

	mutex_unlock(&dsp->mutex);
}
EXPORT_SYMBOL_GPL(sst_mem_block_unregister_all);

/* allocate scratch buffer blocks */
int sst_block_alloc_scratch(struct sst_dsp *dsp)
{
	struct sst_module *module;
	struct sst_block_allocator ba;
	int ret;

	mutex_lock(&dsp->mutex);

	/* calculate required scratch size */
	dsp->scratch_size = 0;
	list_for_each_entry(module, &dsp->module_list, list) {
		dev_dbg(dsp->dev, "module %d scratch req 0x%x bytes\n",
			module->id, module->scratch_size);
		if (dsp->scratch_size < module->scratch_size)
			dsp->scratch_size = module->scratch_size;
	}

	dev_dbg(dsp->dev, "scratch buffer required is 0x%x bytes\n",
		dsp->scratch_size);

	if (dsp->scratch_size == 0) {
		dev_info(dsp->dev, "no modules need scratch buffer\n");
		mutex_unlock(&dsp->mutex);
		return 0;
	}

	/* allocate blocks for module scratch buffers */
	dev_dbg(dsp->dev, "allocating scratch blocks\n");

	ba.size = dsp->scratch_size;
	ba.type = SST_MEM_DRAM;

	/* do we need to allocate at fixed offset */
	if (dsp->scratch_offset != 0) {

		dev_dbg(dsp->dev, "block request 0x%x bytes type %d at 0x%x\n",
			ba.size, ba.type, ba.offset);

		ba.offset = dsp->scratch_offset;

		/* alloc blocks that includes this section */
		ret = block_alloc_fixed(dsp, &ba, &dsp->scratch_block_list);

	} else {
		dev_dbg(dsp->dev, "block request 0x%x bytes type %d\n",
			ba.size, ba.type);

		ba.offset = 0;
		ret = block_alloc(dsp, &ba, &dsp->scratch_block_list);
	}
	if (ret < 0) {
		dev_err(dsp->dev, "error: can't alloc scratch blocks\n");
		mutex_unlock(&dsp->mutex);
		return ret;
	}

	ret = block_list_prepare(dsp, &dsp->scratch_block_list);
	if (ret < 0) {
		dev_err(dsp->dev, "error: scratch block prepare failed\n");
		mutex_unlock(&dsp->mutex);
		return ret;
	}

	/* assign the same offset of scratch to each module */
	dsp->scratch_offset = ba.offset;
	mutex_unlock(&dsp->mutex);
	return dsp->scratch_size;
}
EXPORT_SYMBOL_GPL(sst_block_alloc_scratch);

/* free all scratch blocks */
void sst_block_free_scratch(struct sst_dsp *dsp)
{
	mutex_lock(&dsp->mutex);
	block_list_remove(dsp, &dsp->scratch_block_list);
	mutex_unlock(&dsp->mutex);
}
EXPORT_SYMBOL_GPL(sst_block_free_scratch);

/* get a module from it's unique ID */
struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id)
{
	struct sst_module *module;

	mutex_lock(&dsp->mutex);

	list_for_each_entry(module, &dsp->module_list, list) {
		if (module->id == id) {
			mutex_unlock(&dsp->mutex);
			return module;
		}
	}

	mutex_unlock(&dsp->mutex);
	return NULL;
}
EXPORT_SYMBOL_GPL(sst_module_get_from_id);

struct sst_module_runtime *sst_module_runtime_get_from_id(
	struct sst_module *module, u32 id)
{
	struct sst_module_runtime *runtime;
	struct sst_dsp *dsp = module->dsp;

	mutex_lock(&dsp->mutex);

	list_for_each_entry(runtime, &module->runtime_list, list) {
		if (runtime->id == id) {
			mutex_unlock(&dsp->mutex);
			return runtime;
		}
	}

	mutex_unlock(&dsp->mutex);
	return NULL;
}
EXPORT_SYMBOL_GPL(sst_module_runtime_get_from_id);

/* returns block address in DSP address space */
u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset,
	enum sst_mem_type type)
{
	switch (type) {
	case SST_MEM_IRAM:
		return offset - dsp->addr.iram_offset +
			dsp->addr.dsp_iram_offset;
	case SST_MEM_DRAM:
		return offset - dsp->addr.dram_offset +
			dsp->addr.dsp_dram_offset;
	default:
		return 0;
	}
}
EXPORT_SYMBOL_GPL(sst_dsp_get_offset);

struct sst_dsp *sst_dsp_new(struct device *dev,
	struct sst_dsp_device *sst_dev, struct sst_pdata *pdata)
{
	struct sst_dsp *sst;
	int err;

	dev_dbg(dev, "initialising audio DSP id 0x%x\n", pdata->id);

	sst = devm_kzalloc(dev, sizeof(*sst), GFP_KERNEL);
	if (sst == NULL)
		return NULL;

	spin_lock_init(&sst->spinlock);
	mutex_init(&sst->mutex);
	sst->dev = dev;
	sst->dma_dev = pdata->dma_dev;
	sst->thread_context = sst_dev->thread_context;
	sst->sst_dev = sst_dev;
	sst->id = pdata->id;
	sst->irq = pdata->irq;
	sst->ops = sst_dev->ops;
	sst->pdata = pdata;
	INIT_LIST_HEAD(&sst->used_block_list);
	INIT_LIST_HEAD(&sst->free_block_list);
	INIT_LIST_HEAD(&sst->module_list);
	INIT_LIST_HEAD(&sst->fw_list);
	INIT_LIST_HEAD(&sst->scratch_block_list);

	/* Initialise SST Audio DSP */
	if (sst->ops->init) {
		err = sst->ops->init(sst, pdata);
		if (err < 0)
			return NULL;
	}

	/* Register the ISR */
	err = request_threaded_irq(sst->irq, sst->ops->irq_handler,
		sst_dev->thread, IRQF_SHARED, "AudioDSP", sst);
	if (err)
		goto irq_err;

	err = sst_dma_new(sst);
	if (err)
		dev_warn(dev, "sst_dma_new failed %d\n", err);

	return sst;

irq_err:
	if (sst->ops->free)
		sst->ops->free(sst);

	return NULL;
}
EXPORT_SYMBOL_GPL(sst_dsp_new);

void sst_dsp_free(struct sst_dsp *sst)
{
	free_irq(sst->irq, sst);
	if (sst->ops->free)
		sst->ops->free(sst);

	sst_dma_free(sst->dma);
}
EXPORT_SYMBOL_GPL(sst_dsp_free);

MODULE_DESCRIPTION("Intel SST Firmware Loader");
MODULE_LICENSE("GPL v2");
