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 "ia_css_types.h"
8 #include "sh_css_defs.h"
9 #include "assert_support.h"
10
11 #include "ia_css_ctc2.host.h"
12
13 #define INEFFECTIVE_VAL 4096
14 #define BASIC_VAL 819
15
16 /*Default configuration of parameters for Ctc2*/
17 const struct ia_css_ctc2_config default_ctc2_config = {
18 INEFFECTIVE_VAL, INEFFECTIVE_VAL, INEFFECTIVE_VAL,
19 INEFFECTIVE_VAL, INEFFECTIVE_VAL, INEFFECTIVE_VAL,
20 BASIC_VAL * 2, BASIC_VAL * 4, BASIC_VAL * 6,
21 BASIC_VAL * 8, INEFFECTIVE_VAL, INEFFECTIVE_VAL,
22 BASIC_VAL >> 1, BASIC_VAL
23 };
24
25 /* (dydx) = ctc2_slope(y1, y0, x1, x0)
26 * -----------------------------------------------
27 * Calculation of the Slope of a Line = ((y1 - y0) >> 8)/(x1 - x0)
28 *
29 * Note: y1, y0 , x1 & x0 must lie within the range 0 <-> 8191
30 */
ctc2_slope(int y1,int y0,int x1,int x0)31 static int ctc2_slope(int y1, int y0, int x1, int x0)
32 {
33 const int shift_val = 8;
34 const int max_slope = (1 << IA_CSS_CTC_COEF_SHIFT) - 1;
35 int dy = y1 - y0;
36 int dx = x1 - x0;
37 int rounding = (dx + 1) >> 1;
38 int dy_shift = dy << shift_val;
39 int slope, dydx;
40
41 /*Protection for parameter values, & avoiding zero divisions*/
42 assert(y0 >= 0 && y0 <= max_slope);
43 assert(y1 >= 0 && y1 <= max_slope);
44 assert(x0 >= 0 && x0 <= max_slope);
45 assert(x1 > 0 && x1 <= max_slope);
46 assert(dx > 0);
47
48 if (dy < 0)
49 rounding = -rounding;
50 slope = (int)(dy_shift + rounding) / dx;
51
52 /*the slope must lie within the range
53 (-max_slope-1) >= (dydx) >= (max_slope)
54 */
55 if (slope <= -max_slope - 1) {
56 dydx = -max_slope - 1;
57 } else if (slope >= max_slope) {
58 dydx = max_slope;
59 } else {
60 dydx = slope;
61 }
62
63 return dydx;
64 }
65
66 /* (void) = ia_css_ctc2_vmem_encode(*to, *from)
67 * -----------------------------------------------
68 * VMEM Encode Function to translate Y parameters from userspace into ISP space
69 */
ia_css_ctc2_vmem_encode(struct ia_css_isp_ctc2_vmem_params * to,const struct ia_css_ctc2_config * from,size_t size)70 void ia_css_ctc2_vmem_encode(struct ia_css_isp_ctc2_vmem_params *to,
71 const struct ia_css_ctc2_config *from,
72 size_t size)
73 {
74 unsigned int i, j;
75 const unsigned int shffl_blck = 4;
76 const unsigned int length_zeros = 11;
77 short dydx0, dydx1, dydx2, dydx3, dydx4;
78
79 (void)size;
80 /*
81 * Calculation of slopes of lines interconnecting
82 * 0.0 -> y_x1 -> y_x2 -> y _x3 -> y_x4 -> 1.0
83 */
84 dydx0 = ctc2_slope(from->y_y1, from->y_y0,
85 from->y_x1, 0);
86 dydx1 = ctc2_slope(from->y_y2, from->y_y1,
87 from->y_x2, from->y_x1);
88 dydx2 = ctc2_slope(from->y_y3, from->y_y2,
89 from->y_x3, from->y_x2);
90 dydx3 = ctc2_slope(from->y_y4, from->y_y3,
91 from->y_x4, from->y_x3);
92 dydx4 = ctc2_slope(from->y_y5, from->y_y4,
93 SH_CSS_BAYER_MAXVAL, from->y_x4);
94
95 /*Fill 3 arrays with:
96 * - Luma input gain values y_y0, y_y1, y_y2, y_3, y_y4
97 * - Luma kneepoints 0, y_x1, y_x2, y_x3, y_x4
98 * - Calculated slopes dydx0, dyxd1, dydx2, dydx3, dydx4
99 *
100 * - Each 64-element array is divided in blocks of 16 elements:
101 * the 5 parameters + zeros in the remaining 11 positions
102 * - All blocks of the same array will contain the same data
103 */
104 for (i = 0; i < shffl_blck; i++) {
105 to->y_x[0][(i << shffl_blck)] = 0;
106 to->y_x[0][(i << shffl_blck) + 1] = from->y_x1;
107 to->y_x[0][(i << shffl_blck) + 2] = from->y_x2;
108 to->y_x[0][(i << shffl_blck) + 3] = from->y_x3;
109 to->y_x[0][(i << shffl_blck) + 4] = from->y_x4;
110
111 to->y_y[0][(i << shffl_blck)] = from->y_y0;
112 to->y_y[0][(i << shffl_blck) + 1] = from->y_y1;
113 to->y_y[0][(i << shffl_blck) + 2] = from->y_y2;
114 to->y_y[0][(i << shffl_blck) + 3] = from->y_y3;
115 to->y_y[0][(i << shffl_blck) + 4] = from->y_y4;
116
117 to->e_y_slope[0][(i << shffl_blck)] = dydx0;
118 to->e_y_slope[0][(i << shffl_blck) + 1] = dydx1;
119 to->e_y_slope[0][(i << shffl_blck) + 2] = dydx2;
120 to->e_y_slope[0][(i << shffl_blck) + 3] = dydx3;
121 to->e_y_slope[0][(i << shffl_blck) + 4] = dydx4;
122
123 for (j = 0; j < length_zeros; j++) {
124 to->y_x[0][(i << shffl_blck) + 5 + j] = 0;
125 to->y_y[0][(i << shffl_blck) + 5 + j] = 0;
126 to->e_y_slope[0][(i << shffl_blck) + 5 + j] = 0;
127 }
128 }
129 }
130
131 /* (void) = ia_css_ctc2_encode(*to, *from)
132 * -----------------------------------------------
133 * DMEM Encode Function to translate UV parameters from userspace into ISP space
134 */
ia_css_ctc2_encode(struct ia_css_isp_ctc2_dmem_params * to,struct ia_css_ctc2_config * from,size_t size)135 void ia_css_ctc2_encode(struct ia_css_isp_ctc2_dmem_params *to,
136 struct ia_css_ctc2_config *from,
137 size_t size)
138 {
139 (void)size;
140
141 to->uv_y0 = from->uv_y0;
142 to->uv_y1 = from->uv_y1;
143 to->uv_x0 = from->uv_x0;
144 to->uv_x1 = from->uv_x1;
145
146 /*Slope Calculation*/
147 to->uv_dydx = ctc2_slope(from->uv_y1, from->uv_y0,
148 from->uv_x1, from->uv_x0);
149 }
150