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