/*
 * Copyright (C) 2012-2017 ARM Limited or its affiliates.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "ssi_driver.h"
#include "ssi_sram_mgr.h"

/**
 * struct ssi_sram_mgr_ctx -Internal RAM context manager
 * @sram_free_offset:   the offset to the non-allocated area
 */
struct ssi_sram_mgr_ctx {
	ssi_sram_addr_t sram_free_offset;
};

/**
 * ssi_sram_mgr_fini() - Cleanup SRAM pool.
 *
 * @drvdata: Associated device driver context
 */
void ssi_sram_mgr_fini(struct ssi_drvdata *drvdata)
{
	struct ssi_sram_mgr_ctx *smgr_ctx = drvdata->sram_mgr_handle;

	/* Free "this" context */
	if (smgr_ctx) {
		memset(smgr_ctx, 0, sizeof(struct ssi_sram_mgr_ctx));
		kfree(smgr_ctx);
	}
}

/**
 * ssi_sram_mgr_init() - Initializes SRAM pool.
 *      The pool starts right at the beginning of SRAM.
 *      Returns zero for success, negative value otherwise.
 *
 * @drvdata: Associated device driver context
 */
int ssi_sram_mgr_init(struct ssi_drvdata *drvdata)
{
	struct ssi_sram_mgr_ctx *smgr_ctx;
	int rc;

	/* Allocate "this" context */
	drvdata->sram_mgr_handle = kzalloc(
			sizeof(struct ssi_sram_mgr_ctx), GFP_KERNEL);
	if (!drvdata->sram_mgr_handle) {
		SSI_LOG_ERR("Not enough memory to allocate SRAM_MGR ctx (%zu)\n",
			sizeof(struct ssi_sram_mgr_ctx));
		rc = -ENOMEM;
		goto out;
	}
	smgr_ctx = drvdata->sram_mgr_handle;

	/* Pool starts at start of SRAM */
	smgr_ctx->sram_free_offset = 0;

	return 0;

out:
	ssi_sram_mgr_fini(drvdata);
	return rc;
}

/*!
 * Allocated buffer from SRAM pool.
 * Note: Caller is responsible to free the LAST allocated buffer.
 * This function does not taking care of any fragmentation may occur
 * by the order of calls to alloc/free.
 *
 * \param drvdata
 * \param size The requested bytes to allocate
 */
ssi_sram_addr_t ssi_sram_mgr_alloc(struct ssi_drvdata *drvdata, u32 size)
{
	struct ssi_sram_mgr_ctx *smgr_ctx = drvdata->sram_mgr_handle;
	ssi_sram_addr_t p;

	if (unlikely((size & 0x3) != 0)) {
		SSI_LOG_ERR("Requested buffer size (%u) is not multiple of 4",
			size);
		return NULL_SRAM_ADDR;
	}
	if (unlikely(size > (SSI_CC_SRAM_SIZE - smgr_ctx->sram_free_offset))) {
		SSI_LOG_ERR("Not enough space to allocate %u B (at offset %llu)\n",
			size, smgr_ctx->sram_free_offset);
		return NULL_SRAM_ADDR;
	}

	p = smgr_ctx->sram_free_offset;
	smgr_ctx->sram_free_offset += size;
	SSI_LOG_DEBUG("Allocated %u B @ %u\n", size, (unsigned int)p);
	return p;
}

/**
 * ssi_sram_mgr_const2sram_desc() - Create const descriptors sequence to
 *	set values in given array into SRAM.
 * Note: each const value can't exceed word size.
 *
 * @src:	  A pointer to array of words to set as consts.
 * @dst:	  The target SRAM buffer to set into
 * @nelements:	  The number of words in "src" array
 * @seq:	  A pointer to the given IN/OUT descriptor sequence
 * @seq_len:	  A pointer to the given IN/OUT sequence length
 */
void ssi_sram_mgr_const2sram_desc(
	const u32 *src, ssi_sram_addr_t dst,
	unsigned int nelement,
	struct cc_hw_desc *seq, unsigned int *seq_len)
{
	u32 i;
	unsigned int idx = *seq_len;

	for (i = 0; i < nelement; i++, idx++) {
		hw_desc_init(&seq[idx]);
		set_din_const(&seq[idx], src[i], sizeof(u32));
		set_dout_sram(&seq[idx], dst + (i * sizeof(u32)), sizeof(u32));
		set_flow_mode(&seq[idx], BYPASS);
	}

	*seq_len = idx;
}

