1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include "ia_css_types.h"
17#include "sh_css_defs.h"
18#ifndef IA_CSS_NO_DEBUG
19#include "ia_css_debug.h"
20#endif
21#include "sh_css_frac.h"
22#include "assert_support.h"
23
24#include "bh/bh_2/ia_css_bh.host.h"
25#include "ia_css_s3a.host.h"
26
27const struct ia_css_3a_config default_3a_config = {
28 25559,
29 32768,
30 7209,
31 65535,
32 0,
33 65535,
34 {-3344, -6104, -19143, 19143, 6104, 3344, 0},
35 {1027, 0, -9219, 16384, -9219, 1027, 0}
36};
37
38static unsigned int s3a_raw_bit_depth;
39
40void
41ia_css_s3a_configure(unsigned int raw_bit_depth)
42{
43 s3a_raw_bit_depth = raw_bit_depth;
44}
45
46static void
47ia_css_ae_encode(
48 struct sh_css_isp_ae_params *to,
49 const struct ia_css_3a_config *from,
50 unsigned int size)
51{
52 (void)size;
53
54 to->y_coef_r =
55 uDIGIT_FITTING(from->ae_y_coef_r, 16, SH_CSS_AE_YCOEF_SHIFT);
56 to->y_coef_g =
57 uDIGIT_FITTING(from->ae_y_coef_g, 16, SH_CSS_AE_YCOEF_SHIFT);
58 to->y_coef_b =
59 uDIGIT_FITTING(from->ae_y_coef_b, 16, SH_CSS_AE_YCOEF_SHIFT);
60}
61
62static void
63ia_css_awb_encode(
64 struct sh_css_isp_awb_params *to,
65 const struct ia_css_3a_config *from,
66 unsigned int size)
67{
68 (void)size;
69
70 to->lg_high_raw =
71 uDIGIT_FITTING(from->awb_lg_high_raw, 16, s3a_raw_bit_depth);
72 to->lg_low =
73 uDIGIT_FITTING(from->awb_lg_low, 16, SH_CSS_BAYER_BITS);
74 to->lg_high =
75 uDIGIT_FITTING(from->awb_lg_high, 16, SH_CSS_BAYER_BITS);
76}
77
78static void
79ia_css_af_encode(
80 struct sh_css_isp_af_params *to,
81 const struct ia_css_3a_config *from,
82 unsigned int size)
83{
84 unsigned int i;
85 (void)size;
86
87
88 for (i = 0; i < 7; ++i) {
89 to->fir1[i] =
90 sDIGIT_FITTING(from->af_fir1_coef[i], 15,
91 SH_CSS_AF_FIR_SHIFT);
92 to->fir2[i] =
93 sDIGIT_FITTING(from->af_fir2_coef[i], 15,
94 SH_CSS_AF_FIR_SHIFT);
95 }
96}
97
98void
99ia_css_s3a_encode(
100 struct sh_css_isp_s3a_params *to,
101 const struct ia_css_3a_config *from,
102 unsigned int size)
103{
104 (void)size;
105
106 ia_css_ae_encode(&to->ae, from, sizeof(to->ae));
107 ia_css_awb_encode(&to->awb, from, sizeof(to->awb));
108 ia_css_af_encode(&to->af, from, sizeof(to->af));
109}
110
111#if 0
112void
113ia_css_process_s3a(
114 unsigned int pipe_id,
115 const struct ia_css_pipeline_stage *stage,
116 struct ia_css_isp_parameters *params)
117{
118 short dmem_offset = stage->binary->info->mem_offsets->dmem.s3a;
119
120 assert(params);
121
122 if (dmem_offset >= 0) {
123 ia_css_s3a_encode((struct sh_css_isp_s3a_params *)
124 &stage->isp_mem_params[IA_CSS_ISP_DMEM0].address[dmem_offset],
125 ¶ms->s3a_config);
126 ia_css_bh_encode((struct sh_css_isp_bh_params *)
127 &stage->isp_mem_params[IA_CSS_ISP_DMEM0].address[dmem_offset],
128 ¶ms->s3a_config);
129 params->isp_params_changed = true;
130 params->isp_mem_params_changed[pipe_id][stage->stage_num][IA_CSS_ISP_DMEM0] =
131 true;
132 }
133
134 params->isp_params_changed = true;
135}
136#endif
137
138#ifndef IA_CSS_NO_DEBUG
139void
140ia_css_ae_dump(
141 const struct sh_css_isp_ae_params *ae,
142 unsigned int level)
143{
144 if (!ae) return;
145 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
146 "ae_y_coef_r", ae->y_coef_r);
147 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
148 "ae_y_coef_g", ae->y_coef_g);
149 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
150 "ae_y_coef_b", ae->y_coef_b);
151}
152
153void
154ia_css_awb_dump(
155 const struct sh_css_isp_awb_params *awb,
156 unsigned int level)
157{
158 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
159 "awb_lg_high_raw", awb->lg_high_raw);
160 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
161 "awb_lg_low", awb->lg_low);
162 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
163 "awb_lg_high", awb->lg_high);
164}
165
166void
167ia_css_af_dump(
168 const struct sh_css_isp_af_params *af,
169 unsigned int level)
170{
171 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
172 "af_fir1[0]", af->fir1[0]);
173 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
174 "af_fir1[1]", af->fir1[1]);
175 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
176 "af_fir1[2]", af->fir1[2]);
177 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
178 "af_fir1[3]", af->fir1[3]);
179 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
180 "af_fir1[4]", af->fir1[4]);
181 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
182 "af_fir1[5]", af->fir1[5]);
183 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
184 "af_fir1[6]", af->fir1[6]);
185 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
186 "af_fir2[0]", af->fir2[0]);
187 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
188 "af_fir2[1]", af->fir2[1]);
189 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
190 "af_fir2[2]", af->fir2[2]);
191 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
192 "af_fir2[3]", af->fir2[3]);
193 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
194 "af_fir2[4]", af->fir2[4]);
195 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
196 "af_fir2[5]", af->fir2[5]);
197 ia_css_debug_dtrace(level, "\t%-32s = %d\n",
198 "af_fir2[6]", af->fir2[6]);
199}
200
201void
202ia_css_s3a_dump(
203 const struct sh_css_isp_s3a_params *s3a,
204 unsigned int level)
205{
206 ia_css_debug_dtrace(level, "S3A Support:\n");
207 ia_css_ae_dump(&s3a->ae, level);
208 ia_css_awb_dump(&s3a->awb, level);
209 ia_css_af_dump(&s3a->af, level);
210}
211
212void
213ia_css_s3a_debug_dtrace(
214 const struct ia_css_3a_config *config,
215 unsigned int level)
216{
217 ia_css_debug_dtrace(level,
218 "config.ae_y_coef_r=%d, config.ae_y_coef_g=%d, config.ae_y_coef_b=%d, config.awb_lg_high_raw=%d, config.awb_lg_low=%d, config.awb_lg_high=%d\n",
219 config->ae_y_coef_r, config->ae_y_coef_g,
220 config->ae_y_coef_b, config->awb_lg_high_raw,
221 config->awb_lg_low, config->awb_lg_high);
222}
223#endif
224
225void
226ia_css_s3a_hmem_decode(
227 struct ia_css_3a_statistics *host_stats,
228 const struct ia_css_bh_table *hmem_buf)
229{
230#if defined(HAS_NO_HMEM)
231 (void)host_stats;
232 (void)hmem_buf;
233#else
234 struct ia_css_3a_rgby_output *out_ptr;
235 int i;
236
237
238 int count_for_3a;
239 int sum_r, diff;
240
241 assert(host_stats);
242 assert(host_stats->rgby_data);
243 assert(hmem_buf);
244
245 count_for_3a = host_stats->grid.width * host_stats->grid.height
246 * host_stats->grid.bqs_per_grid_cell
247 * host_stats->grid.bqs_per_grid_cell;
248
249 out_ptr = host_stats->rgby_data;
250
251 ia_css_bh_hmem_decode(out_ptr, hmem_buf);
252
253
254
255 sum_r = 0;
256 for (i = 0; i < HMEM_UNIT_SIZE; i++) {
257 sum_r += out_ptr[i].r;
258 }
259 if (sum_r < count_for_3a) {
260
261 return;
262 }
263
264
265#if 0
266 {
267 int sum_g = 0;
268 int sum_b = 0;
269 int sum_y = 0;
270
271 for (i = 0; i < HMEM_UNIT_SIZE; i++) {
272 sum_g += out_ptr[i].g;
273 sum_b += out_ptr[i].b;
274 sum_y += out_ptr[i].y;
275 }
276 if (sum_g != sum_r || sum_b != sum_r || sum_y != sum_r) {
277
278 return;
279 }
280 }
281#endif
282
283
284
285
286
287
288
289 diff = sum_r - count_for_3a;
290 out_ptr[0].r -= diff;
291 out_ptr[0].g -= diff;
292 out_ptr[0].b -= diff;
293 out_ptr[0].y -= diff;
294#endif
295}
296
297void
298ia_css_s3a_dmem_decode(
299 struct ia_css_3a_statistics *host_stats,
300 const struct ia_css_3a_output *isp_stats)
301{
302 int isp_width, host_width, height, i;
303 struct ia_css_3a_output *host_ptr;
304
305 assert(host_stats);
306 assert(host_stats->data);
307 assert(isp_stats);
308
309 isp_width = host_stats->grid.aligned_width;
310 host_width = host_stats->grid.width;
311 height = host_stats->grid.height;
312 host_ptr = host_stats->data;
313
314
315
316
317 for (i = 0; i < height; i++) {
318 memcpy(host_ptr, isp_stats, host_width * sizeof(*host_ptr));
319 isp_stats += isp_width;
320 host_ptr += host_width;
321 }
322}
323
324
325static inline int
326merge_hi_lo_14(unsigned short hi, unsigned short lo)
327{
328 int val = (int)((((unsigned int)hi << 14) & 0xfffc000) |
329 ((unsigned int)lo & 0x3fff));
330 return val;
331}
332
333void
334ia_css_s3a_vmem_decode(
335 struct ia_css_3a_statistics *host_stats,
336 const u16 *isp_stats_hi,
337 const uint16_t *isp_stats_lo)
338{
339 int out_width, out_height, chunk, rest, kmax, y, x, k, elm_start, elm, ofs;
340 const u16 *hi, *lo;
341 struct ia_css_3a_output *output;
342
343 assert(host_stats);
344 assert(host_stats->data);
345 assert(isp_stats_hi);
346 assert(isp_stats_lo);
347
348 output = host_stats->data;
349 out_width = host_stats->grid.width;
350 out_height = host_stats->grid.height;
351 hi = isp_stats_hi;
352 lo = isp_stats_lo;
353
354 chunk = ISP_VEC_NELEMS >> host_stats->grid.deci_factor_log2;
355 chunk = max(chunk, 1);
356
357 for (y = 0; y < out_height; y++) {
358 elm_start = y * ISP_S3ATBL_HI_LO_STRIDE;
359 rest = out_width;
360 x = 0;
361 while (x < out_width) {
362 kmax = (rest > chunk) ? chunk : rest;
363 ofs = y * out_width + x;
364 elm = elm_start + x * sizeof(*output) / sizeof(int32_t);
365 for (k = 0; k < kmax; k++, elm++) {
366 output[ofs + k].ae_y = merge_hi_lo_14(
367 hi[elm + chunk * 0], lo[elm + chunk * 0]);
368 output[ofs + k].awb_cnt = merge_hi_lo_14(
369 hi[elm + chunk * 1], lo[elm + chunk * 1]);
370 output[ofs + k].awb_gr = merge_hi_lo_14(
371 hi[elm + chunk * 2], lo[elm + chunk * 2]);
372 output[ofs + k].awb_r = merge_hi_lo_14(
373 hi[elm + chunk * 3], lo[elm + chunk * 3]);
374 output[ofs + k].awb_b = merge_hi_lo_14(
375 hi[elm + chunk * 4], lo[elm + chunk * 4]);
376 output[ofs + k].awb_gb = merge_hi_lo_14(
377 hi[elm + chunk * 5], lo[elm + chunk * 5]);
378 output[ofs + k].af_hpf1 = merge_hi_lo_14(
379 hi[elm + chunk * 6], lo[elm + chunk * 6]);
380 output[ofs + k].af_hpf2 = merge_hi_lo_14(
381 hi[elm + chunk * 7], lo[elm + chunk * 7]);
382 }
383 x += chunk;
384 rest -= chunk;
385 }
386 }
387}
388