/*
 * 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 "assert_support.h"
#include "sh_css_metrics.h"

#include "sp.h"
#include "isp.h"

#include "sh_css_internal.h"

#define MULTIPLE_PCS 0
#define SUSPEND      0
#define NOF_PCS      1
#define RESUME_MASK  0x8
#define STOP_MASK    0x0

static bool pc_histogram_enabled;
static struct sh_css_pc_histogram *isp_histogram;
static struct sh_css_pc_histogram *sp_histogram;

struct sh_css_metrics sh_css_metrics;

void
sh_css_metrics_start_frame(void)
{
	sh_css_metrics.frame_metrics.num_frames++;
}

static void
clear_histogram(struct sh_css_pc_histogram *histogram)
{
	unsigned i;

	assert(histogram != NULL);

	for (i = 0; i < histogram->length; i++) {
		histogram->run[i] = 0;
		histogram->stall[i] = 0;
		histogram->msink[i] = 0xFFFF;
	}
}

void
sh_css_metrics_enable_pc_histogram(bool enable)
{
	pc_histogram_enabled = enable;
}

static void
make_histogram(struct sh_css_pc_histogram *histogram, unsigned length)
{
	assert(histogram != NULL);

	if (histogram->length)
		return;
	if (histogram->run)
		return;
	histogram->run = sh_css_malloc(length * sizeof(*histogram->run));
	if (!histogram->run)
		return;
	histogram->stall = sh_css_malloc(length * sizeof(*histogram->stall));
	if (!histogram->stall)
		return;
	histogram->msink = sh_css_malloc(length * sizeof(*histogram->msink));
	if (!histogram->msink)
		return;

	histogram->length = length;
	clear_histogram(histogram);
}

static void
insert_binary_metrics(struct sh_css_binary_metrics **l,
			struct sh_css_binary_metrics *metrics)
{
	assert(l != NULL);
	assert(*l != NULL);
	assert(metrics != NULL);

	for (; *l; l = &(*l)->next)
		if (*l == metrics)
			return;

	*l = metrics;
	metrics->next = NULL;
}

void
sh_css_metrics_start_binary(struct sh_css_binary_metrics *metrics)
{
	assert(metrics != NULL);

	if (!pc_histogram_enabled)
		return;

	isp_histogram = &metrics->isp_histogram;
	sp_histogram = &metrics->sp_histogram;
	make_histogram(isp_histogram, ISP_PMEM_DEPTH);
	make_histogram(sp_histogram, SP_PMEM_DEPTH);
	insert_binary_metrics(&sh_css_metrics.binary_metrics, metrics);
}

void
sh_css_metrics_sample_pcs(void)
{
	bool stall;
	unsigned int pc;
	unsigned int msink;

#if SUSPEND
	unsigned int sc = 0;
	unsigned int stopped_sc = 0;
	unsigned int resume_sc = 0;
#endif


#if MULTIPLE_PCS
	int i;
	unsigned int pc_tab[NOF_PCS];

	for (i = 0; i < NOF_PCS; i++)
		pc_tab[i] = 0;
#endif

	if (!pc_histogram_enabled)
		return;

	if (isp_histogram) {
#if SUSPEND
		/* STOP the ISP */
		isp_ctrl_store(ISP0_ID, ISP_SC_REG, STOP_MASK);
#endif
		msink = isp_ctrl_load(ISP0_ID, ISP_CTRL_SINK_REG);
#if MULTIPLE_PCS
		for (i = 0; i < NOF_PCS; i++)
			pc_tab[i] = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
#else
		pc = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
#endif

#if SUSPEND
		/* RESUME the ISP */
		isp_ctrl_store(ISP0_ID, ISP_SC_REG, RESUME_MASK);
#endif
		isp_histogram->msink[pc] &= msink;
		stall = (msink != 0x7FF);

		if (stall)
			isp_histogram->stall[pc]++;
		else
			isp_histogram->run[pc]++;
	}

	if (sp_histogram && 0) {
		msink = sp_ctrl_load(SP0_ID, SP_CTRL_SINK_REG);
		pc = sp_ctrl_load(SP0_ID, SP_PC_REG);
		sp_histogram->msink[pc] &= msink;
		stall = (msink != 0x7FF);
		if (stall)
			sp_histogram->stall[pc]++;
		else
			sp_histogram->run[pc]++;
	}
}
