// SPDX-License-Identifier: GPL-2.0
/*
 * Support for Intel Camera Imaging ISP subsystem.
 * Copyright (c) 2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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 "ia_css_queue.h"
#include <math_support.h>
#include <ia_css_circbuf.h>
#include <ia_css_circbuf_desc.h>
#include "queue_access.h"

/*****************************************************************************
 * Queue Public APIs
 *****************************************************************************/
int ia_css_queue_local_init(ia_css_queue_t *qhandle, ia_css_queue_local_t *desc)
{
	if (NULL == qhandle || NULL == desc
	    || NULL == desc->cb_elems || NULL == desc->cb_desc) {
		/* Invalid parameters, return error*/
		return -EINVAL;
	}

	/* Mark the queue as Local */
	qhandle->type = IA_CSS_QUEUE_TYPE_LOCAL;

	/* Create a local circular buffer queue*/
	ia_css_circbuf_create(&qhandle->desc.cb_local,
			      desc->cb_elems,
			      desc->cb_desc);

	return 0;
}

int ia_css_queue_remote_init(ia_css_queue_t *qhandle, ia_css_queue_remote_t *desc)
{
	if (NULL == qhandle || NULL == desc) {
		/* Invalid parameters, return error*/
		return -EINVAL;
	}

	/* Mark the queue as remote*/
	qhandle->type = IA_CSS_QUEUE_TYPE_REMOTE;

	/* Copy over the local queue descriptor*/
	qhandle->location = desc->location;
	qhandle->proc_id = desc->proc_id;
	qhandle->desc.remote.cb_desc_addr = desc->cb_desc_addr;
	qhandle->desc.remote.cb_elems_addr = desc->cb_elems_addr;

	/* If queue is remote, we let the local processor
	 * do its init, before using it. This is just to get us
	 * started, we can remove this restriction as we go ahead
	 */

	return 0;
}

int ia_css_queue_uninit(ia_css_queue_t *qhandle)
{
	if (!qhandle)
		return -EINVAL;

	/* Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Local queues are created. Destroy it*/
		ia_css_circbuf_destroy(&qhandle->desc.cb_local);
	}

	return 0;
}

int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item)
{
	int error = 0;

	if (!qhandle)
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		if (ia_css_circbuf_is_full(&qhandle->desc.cb_local)) {
			/* Cannot push the element. Return*/
			return -ENOBUFS;
		}

		/* Push the element*/
		ia_css_circbuf_push(&qhandle->desc.cb_local, item);
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		ia_css_circbuf_desc_t cb_desc;
		ia_css_circbuf_elem_t cb_elem;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		/* a. Load the queue cb_desc from remote */
		QUEUE_CB_DESC_INIT(&cb_desc);
		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* b. Operate on the queue */
		if (ia_css_circbuf_desc_is_full(&cb_desc))
			return -ENOBUFS;

		cb_elem.val = item;

		error = ia_css_queue_item_store(qhandle, cb_desc.end, &cb_elem);
		if (error != 0)
			return error;

		cb_desc.end = (cb_desc.end + 1) % cb_desc.size;

		/* c. Store the queue object */
		/* Set only fields requiring update with
		 * valid value. Avoids uncessary calls
		 * to load/store functions
		 */
		ignore_desc_flags = QUEUE_IGNORE_SIZE_START_STEP_FLAGS;

		error = ia_css_queue_store(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;
	}

	return 0;
}

int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item)
{
	int error = 0;

	if (!qhandle || NULL == item)
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		if (ia_css_circbuf_is_empty(&qhandle->desc.cb_local)) {
			/* Nothing to pop. Return empty queue*/
			return -ENODATA;
		}

		*item = ia_css_circbuf_pop(&qhandle->desc.cb_local);
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		ia_css_circbuf_elem_t cb_elem;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		QUEUE_CB_DESC_INIT(&cb_desc);

		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* b. Operate on the queue */
		if (ia_css_circbuf_desc_is_empty(&cb_desc))
			return -ENODATA;

		error = ia_css_queue_item_load(qhandle, cb_desc.start, &cb_elem);
		if (error != 0)
			return error;

		*item = cb_elem.val;

		cb_desc.start = OP_std_modadd(cb_desc.start, 1, cb_desc.size);

		/* c. Store the queue object */
		/* Set only fields requiring update with
		 * valid value. Avoids uncessary calls
		 * to load/store functions
		 */
		ignore_desc_flags = QUEUE_IGNORE_SIZE_END_STEP_FLAGS;
		error = ia_css_queue_store(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;
	}
	return 0;
}

int ia_css_queue_is_full(ia_css_queue_t *qhandle, bool *is_full)
{
	int error = 0;

	if ((!qhandle) || (!is_full))
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		*is_full = ia_css_circbuf_is_full(&qhandle->desc.cb_local);
		return 0;
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		QUEUE_CB_DESC_INIT(&cb_desc);
		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* b. Operate on the queue */
		*is_full = ia_css_circbuf_desc_is_full(&cb_desc);
		return 0;
	}

	return -EINVAL;
}

int ia_css_queue_get_free_space(ia_css_queue_t *qhandle, uint32_t *size)
{
	int error = 0;

	if ((!qhandle) || (!size))
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		*size = ia_css_circbuf_get_free_elems(&qhandle->desc.cb_local);
		return 0;
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		QUEUE_CB_DESC_INIT(&cb_desc);
		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* b. Operate on the queue */
		*size = ia_css_circbuf_desc_get_free_elems(&cb_desc);
		return 0;
	}

	return -EINVAL;
}

int ia_css_queue_get_used_space(ia_css_queue_t *qhandle, uint32_t *size)
{
	int error = 0;

	if ((!qhandle) || (!size))
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		*size = ia_css_circbuf_get_num_elems(&qhandle->desc.cb_local);
		return 0;
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		QUEUE_CB_DESC_INIT(&cb_desc);
		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* b. Operate on the queue */
		*size = ia_css_circbuf_desc_get_num_elems(&cb_desc);
		return 0;
	}

	return -EINVAL;
}

int ia_css_queue_peek(ia_css_queue_t *qhandle, u32 offset, uint32_t *element)
{
	u32 num_elems = 0;
	int error = 0;

	if ((!qhandle) || (!element))
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		/* Check if offset is valid */
		num_elems = ia_css_circbuf_get_num_elems(&qhandle->desc.cb_local);
		if (offset > num_elems)
			return -EINVAL;

		*element = ia_css_circbuf_peek_from_start(&qhandle->desc.cb_local, (int)offset);
		return 0;
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		ia_css_circbuf_elem_t cb_elem;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		QUEUE_CB_DESC_INIT(&cb_desc);

		error =  ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* Check if offset is valid */
		num_elems = ia_css_circbuf_desc_get_num_elems(&cb_desc);
		if (offset > num_elems)
			return -EINVAL;

		offset = OP_std_modadd(cb_desc.start, offset, cb_desc.size);
		error = ia_css_queue_item_load(qhandle, (uint8_t)offset, &cb_elem);
		if (error != 0)
			return error;

		*element = cb_elem.val;
		return 0;
	}

	return -EINVAL;
}

int ia_css_queue_is_empty(ia_css_queue_t *qhandle, bool *is_empty)
{
	int error = 0;

	if ((!qhandle) || (!is_empty))
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		*is_empty = ia_css_circbuf_is_empty(&qhandle->desc.cb_local);
		return 0;
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		u32 ignore_desc_flags = QUEUE_IGNORE_STEP_FLAG;

		QUEUE_CB_DESC_INIT(&cb_desc);
		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* b. Operate on the queue */
		*is_empty = ia_css_circbuf_desc_is_empty(&cb_desc);
		return 0;
	}

	return -EINVAL;
}

int ia_css_queue_get_size(ia_css_queue_t *qhandle, uint32_t *size)
{
	int error = 0;

	if ((!qhandle) || (!size))
		return -EINVAL;

	/* 1. Load the required queue object */
	if (qhandle->type == IA_CSS_QUEUE_TYPE_LOCAL) {
		/* Directly de-ref the object and
		 * operate on the queue
		 */
		/* Return maximum usable capacity */
		*size = ia_css_circbuf_get_size(&qhandle->desc.cb_local);
	} else if (qhandle->type == IA_CSS_QUEUE_TYPE_REMOTE) {
		/* a. Load the queue from remote */
		ia_css_circbuf_desc_t cb_desc;
		u32 ignore_desc_flags = QUEUE_IGNORE_START_END_STEP_FLAGS;

		QUEUE_CB_DESC_INIT(&cb_desc);

		error = ia_css_queue_load(qhandle, &cb_desc, ignore_desc_flags);
		if (error != 0)
			return error;

		/* Return maximum usable capacity */
		*size = cb_desc.size;
	}

	return 0;
}
