1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Support for Intel Camera Imaging ISP subsystem.
4 * Copyright (c) 2015, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 * more details.
14 */
15
16#include "ia_css_types.h"
17#include "sh_css_defs.h"
18#include "ia_css_debug.h"
19#include "isp.h"
20
21#include "ia_css_ob.host.h"
22
23const struct ia_css_ob_config default_ob_config = {
24	IA_CSS_OB_MODE_NONE,
25	0,
26	0,
27	0,
28	0,
29	0,
30	0
31};
32
33/* TODO: include ob.isp.h to get isp knowledge and
34   add assert on platform restrictions */
35
36void
37ia_css_ob_configure(
38    struct sh_css_isp_ob_stream_config *config,
39    unsigned int isp_pipe_version,
40    unsigned int raw_bit_depth)
41{
42	config->isp_pipe_version = isp_pipe_version;
43	config->raw_bit_depth    = raw_bit_depth;
44}
45
46void
47ia_css_ob_encode(
48    struct sh_css_isp_ob_params *to,
49    const struct ia_css_ob_config *from,
50    const struct sh_css_isp_ob_stream_config *config,
51    unsigned int size)
52{
53	unsigned int ob_bit_depth
54	    = config->isp_pipe_version == 2 ? SH_CSS_BAYER_BITS : config->raw_bit_depth;
55	unsigned int scale = 16 - ob_bit_depth;
56
57	(void)size;
58	switch (from->mode) {
59	case IA_CSS_OB_MODE_FIXED:
60		to->blacklevel_gr = from->level_gr >> scale;
61		to->blacklevel_r  = from->level_r  >> scale;
62		to->blacklevel_b  = from->level_b  >> scale;
63		to->blacklevel_gb = from->level_gb >> scale;
64		to->area_start_bq = 0;
65		to->area_length_bq = 0;
66		to->area_length_bq_inverse = 0;
67		break;
68	case IA_CSS_OB_MODE_RASTER:
69		to->blacklevel_gr = 0;
70		to->blacklevel_r = 0;
71		to->blacklevel_b = 0;
72		to->blacklevel_gb = 0;
73		to->area_start_bq = from->start_position;
74		to->area_length_bq =
75		    (from->end_position - from->start_position) + 1;
76		to->area_length_bq_inverse = AREA_LENGTH_UNIT / to->area_length_bq;
77		break;
78	default:
79		to->blacklevel_gr = 0;
80		to->blacklevel_r = 0;
81		to->blacklevel_b = 0;
82		to->blacklevel_gb = 0;
83		to->area_start_bq = 0;
84		to->area_length_bq = 0;
85		to->area_length_bq_inverse = 0;
86		break;
87	}
88}
89
90void
91ia_css_ob_vmem_encode(
92    struct sh_css_isp_ob_vmem_params *to,
93    const struct ia_css_ob_config *from,
94    const struct sh_css_isp_ob_stream_config *config,
95    unsigned int size)
96{
97	struct sh_css_isp_ob_params tmp;
98	struct sh_css_isp_ob_params *ob = &tmp;
99
100	(void)size;
101	ia_css_ob_encode(&tmp, from, config, sizeof(tmp));
102
103	{
104		unsigned int i;
105		unsigned int sp_obarea_start_bq  = ob->area_start_bq;
106		unsigned int sp_obarea_length_bq = ob->area_length_bq;
107		unsigned int low = sp_obarea_start_bq;
108		unsigned int high = low + sp_obarea_length_bq;
109		u16 all_ones = ~0;
110
111		for (i = 0; i < OBAREA_MASK_SIZE; i++) {
112			if (i >= low && i < high)
113				to->vmask[i / ISP_VEC_NELEMS][i % ISP_VEC_NELEMS] = all_ones;
114			else
115				to->vmask[i / ISP_VEC_NELEMS][i % ISP_VEC_NELEMS] = 0;
116		}
117	}
118}
119
120void
121ia_css_ob_dump(
122    const struct sh_css_isp_ob_params *ob,
123    unsigned int level)
124{
125	if (!ob) return;
126	ia_css_debug_dtrace(level, "Optical Black:\n");
127	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
128			    "ob_blacklevel_gr", ob->blacklevel_gr);
129	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
130			    "ob_blacklevel_r", ob->blacklevel_r);
131	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
132			    "ob_blacklevel_b", ob->blacklevel_b);
133	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
134			    "ob_blacklevel_gb", ob->blacklevel_gb);
135	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
136			    "obarea_start_bq", ob->area_start_bq);
137	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
138			    "obarea_length_bq", ob->area_length_bq);
139	ia_css_debug_dtrace(level, "\t%-32s = %d\n",
140			    "obarea_length_bq_inverse",
141			    ob->area_length_bq_inverse);
142}
143
144void
145ia_css_ob_debug_dtrace(
146    const struct ia_css_ob_config *config,
147    unsigned int level)
148{
149	ia_css_debug_dtrace(level,
150			    "config.mode=%d, config.level_gr=%d, config.level_r=%d, config.level_b=%d,  config.level_gb=%d, config.start_position=%d, config.end_position=%d\n",
151			    config->mode,
152			    config->level_gr, config->level_r,
153			    config->level_b, config->level_gb,
154			    config->start_position, config->end_position);
155}
156