// 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 "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 int i;

	assert(histogram);

	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 int length)
{
	assert(histogram);

	if (histogram->length)
		return;
	if (histogram->run)
		return;
	histogram->run = kvmalloc(length * sizeof(*histogram->run),
				  GFP_KERNEL);
	if (!histogram->run)
		return;
	histogram->stall = kvmalloc(length * sizeof(*histogram->stall),
				    GFP_KERNEL);
	if (!histogram->stall)
		return;
	histogram->msink = kvmalloc(length * sizeof(*histogram->msink),
				    GFP_KERNEL);
	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);
	assert(*l);
	assert(metrics);

	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);

	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]++;
	}
}
