1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Intel Camera Imaging ISP subsystem.
4  * Copyright (c) 2015, Intel Corporation.
5  */
6 
7 #include "assert_support.h"
8 #include "sh_css_metrics.h"
9 
10 #include "sp.h"
11 #include "isp.h"
12 
13 #include "sh_css_internal.h"
14 
15 #define MULTIPLE_PCS 0
16 #define SUSPEND      0
17 #define NOF_PCS      1
18 #define RESUME_MASK  0x8
19 #define STOP_MASK    0x0
20 
21 static bool pc_histogram_enabled;
22 static struct sh_css_pc_histogram *isp_histogram;
23 static struct sh_css_pc_histogram *sp_histogram;
24 
25 struct sh_css_metrics sh_css_metrics;
26 
27 void
sh_css_metrics_start_frame(void)28 sh_css_metrics_start_frame(void)
29 {
30 	sh_css_metrics.frame_metrics.num_frames++;
31 }
32 
33 static void
clear_histogram(struct sh_css_pc_histogram * histogram)34 clear_histogram(struct sh_css_pc_histogram *histogram)
35 {
36 	unsigned int i;
37 
38 	assert(histogram);
39 
40 	for (i = 0; i < histogram->length; i++) {
41 		histogram->run[i] = 0;
42 		histogram->stall[i] = 0;
43 		histogram->msink[i] = 0xFFFF;
44 	}
45 }
46 
47 void
sh_css_metrics_enable_pc_histogram(bool enable)48 sh_css_metrics_enable_pc_histogram(bool enable)
49 {
50 	pc_histogram_enabled = enable;
51 }
52 
53 static void
make_histogram(struct sh_css_pc_histogram * histogram,unsigned int length)54 make_histogram(struct sh_css_pc_histogram *histogram, unsigned int length)
55 {
56 	assert(histogram);
57 
58 	if (histogram->length)
59 		return;
60 	if (histogram->run)
61 		return;
62 	histogram->run = kvmalloc(length * sizeof(*histogram->run),
63 				  GFP_KERNEL);
64 	if (!histogram->run)
65 		return;
66 	histogram->stall = kvmalloc(length * sizeof(*histogram->stall),
67 				    GFP_KERNEL);
68 	if (!histogram->stall)
69 		return;
70 	histogram->msink = kvmalloc(length * sizeof(*histogram->msink),
71 				    GFP_KERNEL);
72 	if (!histogram->msink)
73 		return;
74 
75 	histogram->length = length;
76 	clear_histogram(histogram);
77 }
78 
79 static void
insert_binary_metrics(struct sh_css_binary_metrics ** l,struct sh_css_binary_metrics * metrics)80 insert_binary_metrics(struct sh_css_binary_metrics **l,
81 		      struct sh_css_binary_metrics *metrics)
82 {
83 	assert(l);
84 	assert(*l);
85 	assert(metrics);
86 
87 	for (; *l; l = &(*l)->next)
88 		if (*l == metrics)
89 			return;
90 
91 	*l = metrics;
92 	metrics->next = NULL;
93 }
94 
95 void
sh_css_metrics_start_binary(struct sh_css_binary_metrics * metrics)96 sh_css_metrics_start_binary(struct sh_css_binary_metrics *metrics)
97 {
98 	assert(metrics);
99 
100 	if (!pc_histogram_enabled)
101 		return;
102 
103 	isp_histogram = &metrics->isp_histogram;
104 	sp_histogram = &metrics->sp_histogram;
105 	make_histogram(isp_histogram, ISP_PMEM_DEPTH);
106 	make_histogram(sp_histogram, SP_PMEM_DEPTH);
107 	insert_binary_metrics(&sh_css_metrics.binary_metrics, metrics);
108 }
109 
110 void
sh_css_metrics_sample_pcs(void)111 sh_css_metrics_sample_pcs(void)
112 {
113 	bool stall;
114 	unsigned int pc;
115 	unsigned int msink;
116 
117 
118 
119 	if (!pc_histogram_enabled)
120 		return;
121 
122 	if (isp_histogram) {
123 		msink = isp_ctrl_load(ISP0_ID, ISP_CTRL_SINK_REG);
124 		pc = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
125 
126 		isp_histogram->msink[pc] &= msink;
127 		stall = (msink != 0x7FF);
128 
129 		if (stall)
130 			isp_histogram->stall[pc]++;
131 		else
132 			isp_histogram->run[pc]++;
133 	}
134 
135 	if (sp_histogram && 0) {
136 		msink = sp_ctrl_load(SP0_ID, SP_CTRL_SINK_REG);
137 		pc = sp_ctrl_load(SP0_ID, SP_PC_REG);
138 		sp_histogram->msink[pc] &= msink;
139 		stall = (msink != 0x7FF);
140 		if (stall)
141 			sp_histogram->stall[pc]++;
142 		else
143 			sp_histogram->run[pc]++;
144 	}
145 }
146