GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / staging / media / atomisp / pci / atomisp2 / css2400 / sh_css_metrics.c
1 /*
2  * Support for Intel Camera Imaging ISP subsystem.
3  * Copyright (c) 2015, Intel Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  */
14
15 #include "assert_support.h"
16 #include "sh_css_metrics.h"
17
18 #include "sp.h"
19 #include "isp.h"
20
21 #include "sh_css_internal.h"
22
23 #define MULTIPLE_PCS 0
24 #define SUSPEND      0
25 #define NOF_PCS      1
26 #define RESUME_MASK  0x8
27 #define STOP_MASK    0x0
28
29 static bool pc_histogram_enabled;
30 static struct sh_css_pc_histogram *isp_histogram;
31 static struct sh_css_pc_histogram *sp_histogram;
32
33 struct sh_css_metrics sh_css_metrics;
34
35 void
36 sh_css_metrics_start_frame(void)
37 {
38         sh_css_metrics.frame_metrics.num_frames++;
39 }
40
41 static void
42 clear_histogram(struct sh_css_pc_histogram *histogram)
43 {
44         unsigned i;
45
46         assert(histogram != NULL);
47
48         for (i = 0; i < histogram->length; i++) {
49                 histogram->run[i] = 0;
50                 histogram->stall[i] = 0;
51                 histogram->msink[i] = 0xFFFF;
52         }
53 }
54
55 void
56 sh_css_metrics_enable_pc_histogram(bool enable)
57 {
58         pc_histogram_enabled = enable;
59 }
60
61 static void
62 make_histogram(struct sh_css_pc_histogram *histogram, unsigned length)
63 {
64         assert(histogram != NULL);
65
66         if (histogram->length)
67                 return;
68         if (histogram->run)
69                 return;
70         histogram->run = sh_css_malloc(length * sizeof(*histogram->run));
71         if (!histogram->run)
72                 return;
73         histogram->stall = sh_css_malloc(length * sizeof(*histogram->stall));
74         if (!histogram->stall)
75                 return;
76         histogram->msink = sh_css_malloc(length * sizeof(*histogram->msink));
77         if (!histogram->msink)
78                 return;
79
80         histogram->length = length;
81         clear_histogram(histogram);
82 }
83
84 static void
85 insert_binary_metrics(struct sh_css_binary_metrics **l,
86                         struct sh_css_binary_metrics *metrics)
87 {
88         assert(l != NULL);
89         assert(*l != NULL);
90         assert(metrics != NULL);
91
92         for (; *l; l = &(*l)->next)
93                 if (*l == metrics)
94                         return;
95
96         *l = metrics;
97         metrics->next = NULL;
98 }
99
100 void
101 sh_css_metrics_start_binary(struct sh_css_binary_metrics *metrics)
102 {
103         assert(metrics != NULL);
104
105         if (!pc_histogram_enabled)
106                 return;
107
108         isp_histogram = &metrics->isp_histogram;
109         sp_histogram = &metrics->sp_histogram;
110         make_histogram(isp_histogram, ISP_PMEM_DEPTH);
111         make_histogram(sp_histogram, SP_PMEM_DEPTH);
112         insert_binary_metrics(&sh_css_metrics.binary_metrics, metrics);
113 }
114
115 void
116 sh_css_metrics_sample_pcs(void)
117 {
118         bool stall;
119         unsigned int pc;
120         unsigned int msink;
121
122 #if SUSPEND
123         unsigned int sc = 0;
124         unsigned int stopped_sc = 0;
125         unsigned int resume_sc = 0;
126 #endif
127
128
129 #if MULTIPLE_PCS
130         int i;
131         unsigned int pc_tab[NOF_PCS];
132
133         for (i = 0; i < NOF_PCS; i++)
134                 pc_tab[i] = 0;
135 #endif
136
137         if (!pc_histogram_enabled)
138                 return;
139
140         if (isp_histogram) {
141 #if SUSPEND
142                 /* STOP the ISP */
143                 isp_ctrl_store(ISP0_ID, ISP_SC_REG, STOP_MASK);
144 #endif
145                 msink = isp_ctrl_load(ISP0_ID, ISP_CTRL_SINK_REG);
146 #if MULTIPLE_PCS
147                 for (i = 0; i < NOF_PCS; i++)
148                         pc_tab[i] = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
149 #else
150                 pc = isp_ctrl_load(ISP0_ID, ISP_PC_REG);
151 #endif
152
153 #if SUSPEND
154                 /* RESUME the ISP */
155                 isp_ctrl_store(ISP0_ID, ISP_SC_REG, RESUME_MASK);
156 #endif
157                 isp_histogram->msink[pc] &= msink;
158                 stall = (msink != 0x7FF);
159
160                 if (stall)
161                         isp_histogram->stall[pc]++;
162                 else
163                         isp_histogram->run[pc]++;
164         }
165
166         if (sp_histogram && 0) {
167                 msink = sp_ctrl_load(SP0_ID, SP_CTRL_SINK_REG);
168                 pc = sp_ctrl_load(SP0_ID, SP_PC_REG);
169                 sp_histogram->msink[pc] &= msink;
170                 stall = (msink != 0x7FF);
171                 if (stall)
172                         sp_histogram->stall[pc]++;
173                 else
174                         sp_histogram->run[pc]++;
175         }
176 }