/*
 * Copyright (c) 2016, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the Intel Corporation nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Author: Yan Wang <yan.wang@linux.intel.com>
 */

#include <sof/trace.h>
#include <sof/dma-trace.h>
#include <sof/ipc.h>
#include <sof/sof.h>
#include <sof/alloc.h>
#include <arch/cache.h>
#include <platform/timer.h>
#include <platform/dma.h>
#include <platform/platform.h>
#include <sof/lock.h>
#include <stdint.h>

static struct dma_trace_data *trace_data = NULL;

static int dma_trace_get_avali_data(struct dma_trace_data *d,
				    struct dma_trace_buf *buffer,
				    int avail);

static uint64_t trace_work(void *data, uint64_t delay)
{
	struct dma_trace_data *d = (struct dma_trace_data *)data;
	struct dma_trace_buf *buffer = &d->dmatb;
	struct dma_sg_config *config = &d->config;
	unsigned long flags;
	uint32_t avail = buffer->avail;
	int32_t size;
	uint32_t overflow;

	/* make sure we don't write more than buffer */
	if (avail > DMA_TRACE_LOCAL_SIZE) {
		overflow = avail - DMA_TRACE_LOCAL_SIZE;
		avail = DMA_TRACE_LOCAL_SIZE;
	} else {
		overflow = 0;
	}

	/* dma gateway supports wrap mode copy, but GPDMA doesn't*/
	/* support, so do it differently based on HW features */
	size = dma_trace_get_avali_data(d, buffer, avail);

	/* any data to copy ? */
	if (size == 0)
		return DMA_TRACE_PERIOD;

	d->overflow = overflow;

	/* DMA trace copying is working */
	d->copy_in_progress = 1;

	/* copy this section to host */
	size = dma_copy_to_host_nowait(&d->dc, config, d->host_offset,
		buffer->r_ptr, size);
	if (size < 0) {
		trace_buffer_error("ebb");
		goto out;
	}

	/* update host pointer and check for wrap */
	d->host_offset += size;
	if (d->host_offset >= d->host_size)
		d->host_offset -= d->host_size;

	/* update local pointer and check for wrap */
	buffer->r_ptr += size;
	if (buffer->r_ptr >= buffer->end_addr)
		buffer->r_ptr -= DMA_TRACE_LOCAL_SIZE;

out:
	spin_lock_irq(&d->lock, flags);

	/* disregard any old messages and dont resend them if we overflow */
	if (size > 0) {
		if (d->overflow)
			buffer->avail = DMA_TRACE_LOCAL_SIZE - size;
		else
			buffer->avail -= size;
	}

	/* DMA trace copying is done, allow reschedule */
	d->copy_in_progress = 0;

	spin_unlock_irq(&d->lock, flags);

	/* reschedule the trace copying work */
	return DMA_TRACE_PERIOD;
}

int dma_trace_init_early(struct sof *sof)
{
	struct dma_trace_buf *buffer;

	trace_data = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, sizeof(*trace_data));
	buffer = &trace_data->dmatb;

	/* allocate new buffer */
	buffer->addr = rballoc(RZONE_RUNTIME,
			       SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA,
			       DMA_TRACE_LOCAL_SIZE);
	if (buffer->addr == NULL) {
		trace_buffer_error("ebm");
		return -ENOMEM;
	}

	bzero(buffer->addr, DMA_TRACE_LOCAL_SIZE);

	/* initialise the DMA buffer */
	buffer->size = DMA_TRACE_LOCAL_SIZE;
	buffer->w_ptr = buffer->r_ptr = buffer->addr;
	buffer->end_addr = buffer->addr + buffer->size;
	buffer->avail = 0;

	list_init(&trace_data->config.elem_list);
	spinlock_init(&trace_data->lock);
	sof->dmat = trace_data;

	return 0;
}

int dma_trace_init_complete(struct dma_trace_data *d)
{
	struct dma_trace_buf *buffer = &d->dmatb;
	int ret;

	trace_buffer("dtn");

	/* init DMA copy context */
	ret = dma_copy_new(&d->dc);
	if (ret < 0) {
		trace_buffer_error("edm");
		rfree(buffer->addr);
		return ret;
	}

	work_init(&d->dmat_work, trace_work, d, WORK_ASYNC);

	return 0;
}

int dma_trace_host_buffer(struct dma_trace_data *d, struct dma_sg_elem *elem,
		uint32_t host_size)
{
	struct dma_sg_elem *e;

	/* allocate new host DMA elem and add it to our list */
	e = rzalloc(RZONE_RUNTIME, SOF_MEM_CAPS_RAM, sizeof(*e));
	if (e == NULL)
		return -ENOMEM;

	/* copy fields - excluding possibly non-initialized elem->src */
	e->dest = elem->dest;
	e->size = elem->size;

	d->host_size = host_size;

	list_item_append(&e->list, &d->config.elem_list);
	return 0;
}

#if defined CONFIG_DMA_GW

static int dma_trace_start(struct dma_trace_data *d)
{
	struct dma_sg_config config;
	struct dma_sg_elem *e;
	uint32_t elem_size, elem_addr, elem_num;
	int err = 0;
	int i;

	err = dma_copy_set_stream_tag(&d->dc, d->stream_tag);
	if (err < 0)
		return err;

	/* size of every trace record */
	elem_size = sizeof(uint64_t) * 2;

	/* Initialize address of local elem */
	elem_addr = (uint32_t)d->dmatb.addr;

	/* the number of elem list */
	elem_num = DMA_TRACE_LOCAL_SIZE / elem_size;

	config.direction = DMA_DIR_LMEM_TO_HMEM;
	config.src_width = sizeof(uint32_t);
	config.dest_width = sizeof(uint32_t);
	config.cyclic = 0;
	list_init(&config.elem_list);

	/* generate local elem list for local trace buffer */
	e = rzalloc(RZONE_SYS, SOF_MEM_CAPS_RAM, sizeof(*e) * elem_num);
	if (!e)
		return -ENOMEM;

	for (i = 0; i < elem_num; i++) {
		e[i].dest = 0;
		e[i].src = elem_addr;
		e[i].size = elem_size; /* the minimum size of DMA copy */

		list_item_append(&e[i].list, &config.elem_list);
		elem_addr += elem_size;
	}

	err = dma_set_config(d->dc.dmac, d->dc.chan, &config);
	if (err < 0) {
		rfree(e);
		return err;
	}

	err = dma_start(d->dc.dmac, d->dc.chan);

	rfree(e);
	return err;
}

static int dma_trace_get_avali_data(struct dma_trace_data *d,
				    struct dma_trace_buf *buffer,
				    int avail)
{
	int size;

	/* there isn't DMA completion callback in GW DMA copying.
	 * so we send previous position always before the next copying
	 * for guaranteeing previous DMA copying is finished.
	 * This function will be called once every 500ms at least even
	 * if no new trace is filled.
	 */
	if (d->old_host_offset != d->host_offset) {
		ipc_dma_trace_send_position();
		d->old_host_offset = d->host_offset;
	}

	if (avail == 0)
		return 0;

	/* writeback trace data */
	if (buffer->r_ptr + avail <= buffer->end_addr) {
		dcache_writeback_region((void *)buffer->r_ptr, avail);
	} else {
		size = buffer->end_addr - buffer->r_ptr + 1;

		/* warp case, flush tail and head of trace buffer */
		dcache_writeback_region((void *)buffer->r_ptr, size);
		dcache_writeback_region((void *)buffer->addr, avail - size);
	}

	return avail;
}
#else
static int dma_trace_get_avali_data(struct dma_trace_data *d,
				    struct dma_trace_buf *buffer,
				    int avail)
{
	uint32_t hsize;
	uint32_t lsize;
	int32_t size;

	/* copy to host in sections if we wrap */
	lsize = avail;
	hsize = avail;

	if (avail == 0)
		return 0;

	/* host buffer wrap ? */
	if (d->host_offset + avail > d->host_size)
		hsize = d->host_size - d->host_offset;

	/* local buffer wrap ? */
	if (buffer->r_ptr + avail > buffer->end_addr)
		lsize = buffer->end_addr - buffer->r_ptr;

	/* get smallest size */
	if (hsize < lsize)
		size = hsize;
	else
		size = lsize;

	/* writeback trace data */
	dcache_writeback_region((void *)buffer->r_ptr, size);

	return size;
}
#endif

int dma_trace_enable(struct dma_trace_data *d)
{
#if defined CONFIG_DMA_GW
	int err;

	/*
	 * GW DMA need finish DMA config and start before
	 * host driver trigger start DMA
	 */
	err = dma_trace_start(d);
	if (err < 0)
		return err;
#endif

	/* validate DMA context */
	if (d->dc.dmac == NULL || d->dc.chan < 0) {
		trace_error_atomic(TRACE_CLASS_BUFFER, "eem");
		return -ENODEV;
	}

	d->enabled = 1;
	work_schedule_default(&d->dmat_work, DMA_TRACE_PERIOD);
	return 0;
}

void dma_trace_flush(void *t)
{
	struct dma_trace_buf *buffer = &trace_data->dmatb;
	uint32_t avail = buffer->avail;
	int32_t size;
	int32_t wrap_count;

	/* number of bytes to flush */
	if (avail > DMA_FLUSH_TRACE_SIZE) {
		size = DMA_FLUSH_TRACE_SIZE;
	} else {
		/* check for buffer wrap */
		if (buffer->w_ptr > buffer->r_ptr)
			size = buffer->w_ptr - buffer->r_ptr;
		else
			size = buffer->end_addr - buffer->r_ptr +
				buffer->w_ptr - buffer->addr;
	}

	/* check for buffer wrap */
	if (buffer->w_ptr - size < buffer->addr) {
		wrap_count = buffer->w_ptr - buffer->addr;
		memcpy(t, buffer->end_addr - (size - wrap_count),
		       size - wrap_count);
		memcpy(t + (size - wrap_count), buffer->addr,
		       wrap_count);
	} else {
		memcpy(t, buffer->w_ptr - size, size);
	}

	/* writeback trace data */
	dcache_writeback_region(t, size);
}

static void dtrace_add_event(const char *e, uint32_t length)
{
	struct dma_trace_buf *buffer = &trace_data->dmatb;
	int margin;

	margin = buffer->end_addr - buffer->w_ptr;

	/* check for buffer wrap */
	if (margin > length) {
		/* no wrap */
		memcpy(buffer->w_ptr, e, length);
		buffer->w_ptr += length;
	} else {

		/* data is bigger than remaining margin so we wrap */
		memcpy(buffer->w_ptr, e, margin);
		buffer->w_ptr = buffer->addr;

		memcpy(buffer->w_ptr, e + margin, length - margin);
		buffer->w_ptr += length - margin;
	}

	buffer->avail += length;
	trace_data->messages++;
}

void dtrace_event(const char *e, uint32_t length)
{
	struct dma_trace_buf *buffer = NULL;
	unsigned long flags;

	if (trace_data == NULL ||
		length > DMA_TRACE_LOCAL_SIZE / 8 || length == 0)
		return;

	buffer = &trace_data->dmatb;

	spin_lock_irq(&trace_data->lock, flags);
	dtrace_add_event(e, length);

	/* if DMA trace copying is working */
	/* don't check if local buffer is half full */
	if (trace_data->copy_in_progress) {
		spin_unlock_irq(&trace_data->lock, flags);
		return;
	}

	spin_unlock_irq(&trace_data->lock, flags);

	/* schedule copy now if buffer > 50% full */
	if (trace_data->enabled &&
	    buffer->avail >= (DMA_TRACE_LOCAL_SIZE / 2)) {
		work_reschedule_default(&trace_data->dmat_work,
		DMA_TRACE_RESCHEDULE_TIME);
		/* reschedule should not be intrrupted */
		/* just like we are in copy progress */
		trace_data->copy_in_progress = 1;
	}

}

void dtrace_event_atomic(const char *e, uint32_t length)
{
	if (trace_data == NULL ||
		length > DMA_TRACE_LOCAL_SIZE / 8 || length == 0)
		return;

	dtrace_add_event(e, length);
}
