1 /*
2  * v4l2-tpg-core.c - Test Pattern Generator
3  *
4  * Note: gen_twopix and tpg_gen_text are based on code from vivi.c. See the
5  * vivi.c source for the copyright information of those functions.
6  *
7  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8  *
9  * This program is free software; you may redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; version 2 of the License.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
17  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
18  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22 
23 #include <linux/module.h>
24 #include <media/v4l2-tpg.h>
25 
26 /* Must remain in sync with enum tpg_pattern */
27 const char * const tpg_pattern_strings[] = {
28 	"75% Colorbar",
29 	"100% Colorbar",
30 	"CSC Colorbar",
31 	"Horizontal 100% Colorbar",
32 	"100% Color Squares",
33 	"100% Black",
34 	"100% White",
35 	"100% Red",
36 	"100% Green",
37 	"100% Blue",
38 	"16x16 Checkers",
39 	"2x2 Checkers",
40 	"1x1 Checkers",
41 	"2x2 Red/Green Checkers",
42 	"1x1 Red/Green Checkers",
43 	"Alternating Hor Lines",
44 	"Alternating Vert Lines",
45 	"One Pixel Wide Cross",
46 	"Two Pixels Wide Cross",
47 	"Ten Pixels Wide Cross",
48 	"Gray Ramp",
49 	"Noise",
50 	NULL
51 };
52 EXPORT_SYMBOL_GPL(tpg_pattern_strings);
53 
54 /* Must remain in sync with enum tpg_aspect */
55 const char * const tpg_aspect_strings[] = {
56 	"Source Width x Height",
57 	"4x3",
58 	"14x9",
59 	"16x9",
60 	"16x9 Anamorphic",
61 	NULL
62 };
63 EXPORT_SYMBOL_GPL(tpg_aspect_strings);
64 
65 /*
66  * Sine table: sin[0] = 127 * sin(-180 degrees)
67  *             sin[128] = 127 * sin(0 degrees)
68  *             sin[256] = 127 * sin(180 degrees)
69  */
70 static const s8 sin[257] = {
71 	   0,   -4,   -7,  -11,  -13,  -18,  -20,  -22,  -26,  -29,  -33,  -35,  -37,  -41,  -43,  -48,
72 	 -50,  -52,  -56,  -58,  -62,  -63,  -65,  -69,  -71,  -75,  -76,  -78,  -82,  -83,  -87,  -88,
73 	 -90,  -93,  -94,  -97,  -99, -101, -103, -104, -107, -108, -110, -111, -112, -114, -115, -117,
74 	-118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -127, -127, -127, -127,
75 	-127, -127, -127, -127, -126, -126, -125, -125, -124, -124, -123, -122, -121, -120, -119, -118,
76 	-117, -116, -114, -113, -111, -110, -109, -107, -105, -103, -101, -100,  -97,  -96,  -93,  -91,
77 	 -90,  -87,  -85,  -82,  -80,  -76,  -75,  -73,  -69,  -67,  -63,  -62,  -60,  -56,  -54,  -50,
78 	 -48,  -46,  -41,  -39,  -35,  -33,  -31,  -26,  -24,  -20,  -18,  -15,  -11,   -9,   -4,   -2,
79 	   0,    2,    4,    9,   11,   15,   18,   20,   24,   26,   31,   33,   35,   39,   41,   46,
80 	  48,   50,   54,   56,   60,   62,   64,   67,   69,   73,   75,   76,   80,   82,   85,   87,
81 	  90,   91,   93,   96,   97,  100,  101,  103,  105,  107,  109,  110,  111,  113,  114,  116,
82 	 117,  118,  119,  120,  121,  122,  123,  124,  124,  125,  125,  126,  126,  127,  127,  127,
83 	 127,  127,  127,  127,  127,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,
84 	 118,  117,  115,  114,  112,  111,  110,  108,  107,  104,  103,  101,   99,   97,   94,   93,
85 	  90,   88,   87,   83,   82,   78,   76,   75,   71,   69,   65,   64,   62,   58,   56,   52,
86 	  50,   48,   43,   41,   37,   35,   33,   29,   26,   22,   20,   18,   13,   11,    7,    4,
87 	   0,
88 };
89 
90 #define cos(idx) sin[((idx) + 64) % sizeof(sin)]
91 
92 /* Global font descriptor */
93 static const u8 *font8x16;
94 
95 void tpg_set_font(const u8 *f)
96 {
97 	font8x16 = f;
98 }
99 EXPORT_SYMBOL_GPL(tpg_set_font);
100 
101 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
102 {
103 	memset(tpg, 0, sizeof(*tpg));
104 	tpg->scaled_width = tpg->src_width = w;
105 	tpg->src_height = tpg->buf_height = h;
106 	tpg->crop.width = tpg->compose.width = w;
107 	tpg->crop.height = tpg->compose.height = h;
108 	tpg->recalc_colors = true;
109 	tpg->recalc_square_border = true;
110 	tpg->brightness = 128;
111 	tpg->contrast = 128;
112 	tpg->saturation = 128;
113 	tpg->hue = 0;
114 	tpg->mv_hor_mode = TPG_MOVE_NONE;
115 	tpg->mv_vert_mode = TPG_MOVE_NONE;
116 	tpg->field = V4L2_FIELD_NONE;
117 	tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
118 	tpg->colorspace = V4L2_COLORSPACE_SRGB;
119 	tpg->perc_fill = 100;
120 	tpg->hsv_enc = V4L2_HSV_ENC_180;
121 }
122 EXPORT_SYMBOL_GPL(tpg_init);
123 
124 int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
125 {
126 	unsigned pat;
127 	unsigned plane;
128 
129 	tpg->max_line_width = max_w;
130 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
131 		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
132 			unsigned pixelsz = plane ? 2 : 4;
133 
134 			tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
135 			if (!tpg->lines[pat][plane])
136 				return -ENOMEM;
137 			if (plane == 0)
138 				continue;
139 			tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
140 			if (!tpg->downsampled_lines[pat][plane])
141 				return -ENOMEM;
142 		}
143 	}
144 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
145 		unsigned pixelsz = plane ? 2 : 4;
146 
147 		tpg->contrast_line[plane] = vzalloc(max_w * pixelsz);
148 		if (!tpg->contrast_line[plane])
149 			return -ENOMEM;
150 		tpg->black_line[plane] = vzalloc(max_w * pixelsz);
151 		if (!tpg->black_line[plane])
152 			return -ENOMEM;
153 		tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz);
154 		if (!tpg->random_line[plane])
155 			return -ENOMEM;
156 	}
157 	return 0;
158 }
159 EXPORT_SYMBOL_GPL(tpg_alloc);
160 
161 void tpg_free(struct tpg_data *tpg)
162 {
163 	unsigned pat;
164 	unsigned plane;
165 
166 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
167 		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
168 			vfree(tpg->lines[pat][plane]);
169 			tpg->lines[pat][plane] = NULL;
170 			if (plane == 0)
171 				continue;
172 			vfree(tpg->downsampled_lines[pat][plane]);
173 			tpg->downsampled_lines[pat][plane] = NULL;
174 		}
175 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
176 		vfree(tpg->contrast_line[plane]);
177 		vfree(tpg->black_line[plane]);
178 		vfree(tpg->random_line[plane]);
179 		tpg->contrast_line[plane] = NULL;
180 		tpg->black_line[plane] = NULL;
181 		tpg->random_line[plane] = NULL;
182 	}
183 }
184 EXPORT_SYMBOL_GPL(tpg_free);
185 
186 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
187 {
188 	tpg->fourcc = fourcc;
189 	tpg->planes = 1;
190 	tpg->buffers = 1;
191 	tpg->recalc_colors = true;
192 	tpg->interleaved = false;
193 	tpg->vdownsampling[0] = 1;
194 	tpg->hdownsampling[0] = 1;
195 	tpg->hmask[0] = ~0;
196 	tpg->hmask[1] = ~0;
197 	tpg->hmask[2] = ~0;
198 
199 	switch (fourcc) {
200 	case V4L2_PIX_FMT_SBGGR8:
201 	case V4L2_PIX_FMT_SGBRG8:
202 	case V4L2_PIX_FMT_SGRBG8:
203 	case V4L2_PIX_FMT_SRGGB8:
204 	case V4L2_PIX_FMT_SBGGR10:
205 	case V4L2_PIX_FMT_SGBRG10:
206 	case V4L2_PIX_FMT_SGRBG10:
207 	case V4L2_PIX_FMT_SRGGB10:
208 	case V4L2_PIX_FMT_SBGGR12:
209 	case V4L2_PIX_FMT_SGBRG12:
210 	case V4L2_PIX_FMT_SGRBG12:
211 	case V4L2_PIX_FMT_SRGGB12:
212 		tpg->interleaved = true;
213 		tpg->vdownsampling[1] = 1;
214 		tpg->hdownsampling[1] = 1;
215 		tpg->planes = 2;
216 		/* fall through */
217 	case V4L2_PIX_FMT_RGB332:
218 	case V4L2_PIX_FMT_RGB565:
219 	case V4L2_PIX_FMT_RGB565X:
220 	case V4L2_PIX_FMT_RGB444:
221 	case V4L2_PIX_FMT_XRGB444:
222 	case V4L2_PIX_FMT_ARGB444:
223 	case V4L2_PIX_FMT_RGB555:
224 	case V4L2_PIX_FMT_XRGB555:
225 	case V4L2_PIX_FMT_ARGB555:
226 	case V4L2_PIX_FMT_RGB555X:
227 	case V4L2_PIX_FMT_XRGB555X:
228 	case V4L2_PIX_FMT_ARGB555X:
229 	case V4L2_PIX_FMT_BGR666:
230 	case V4L2_PIX_FMT_RGB24:
231 	case V4L2_PIX_FMT_BGR24:
232 	case V4L2_PIX_FMT_RGB32:
233 	case V4L2_PIX_FMT_BGR32:
234 	case V4L2_PIX_FMT_XRGB32:
235 	case V4L2_PIX_FMT_XBGR32:
236 	case V4L2_PIX_FMT_ARGB32:
237 	case V4L2_PIX_FMT_ABGR32:
238 		tpg->color_enc = TGP_COLOR_ENC_RGB;
239 		break;
240 	case V4L2_PIX_FMT_GREY:
241 	case V4L2_PIX_FMT_Y16:
242 	case V4L2_PIX_FMT_Y16_BE:
243 		tpg->color_enc = TGP_COLOR_ENC_LUMA;
244 		break;
245 	case V4L2_PIX_FMT_YUV444:
246 	case V4L2_PIX_FMT_YUV555:
247 	case V4L2_PIX_FMT_YUV565:
248 	case V4L2_PIX_FMT_YUV32:
249 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
250 		break;
251 	case V4L2_PIX_FMT_YUV420M:
252 	case V4L2_PIX_FMT_YVU420M:
253 		tpg->buffers = 3;
254 		/* fall through */
255 	case V4L2_PIX_FMT_YUV420:
256 	case V4L2_PIX_FMT_YVU420:
257 		tpg->vdownsampling[1] = 2;
258 		tpg->vdownsampling[2] = 2;
259 		tpg->hdownsampling[1] = 2;
260 		tpg->hdownsampling[2] = 2;
261 		tpg->planes = 3;
262 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
263 		break;
264 	case V4L2_PIX_FMT_YUV422M:
265 	case V4L2_PIX_FMT_YVU422M:
266 		tpg->buffers = 3;
267 		/* fall through */
268 	case V4L2_PIX_FMT_YUV422P:
269 		tpg->vdownsampling[1] = 1;
270 		tpg->vdownsampling[2] = 1;
271 		tpg->hdownsampling[1] = 2;
272 		tpg->hdownsampling[2] = 2;
273 		tpg->planes = 3;
274 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
275 		break;
276 	case V4L2_PIX_FMT_NV16M:
277 	case V4L2_PIX_FMT_NV61M:
278 		tpg->buffers = 2;
279 		/* fall through */
280 	case V4L2_PIX_FMT_NV16:
281 	case V4L2_PIX_FMT_NV61:
282 		tpg->vdownsampling[1] = 1;
283 		tpg->hdownsampling[1] = 1;
284 		tpg->hmask[1] = ~1;
285 		tpg->planes = 2;
286 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
287 		break;
288 	case V4L2_PIX_FMT_NV12M:
289 	case V4L2_PIX_FMT_NV21M:
290 		tpg->buffers = 2;
291 		/* fall through */
292 	case V4L2_PIX_FMT_NV12:
293 	case V4L2_PIX_FMT_NV21:
294 		tpg->vdownsampling[1] = 2;
295 		tpg->hdownsampling[1] = 1;
296 		tpg->hmask[1] = ~1;
297 		tpg->planes = 2;
298 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
299 		break;
300 	case V4L2_PIX_FMT_YUV444M:
301 	case V4L2_PIX_FMT_YVU444M:
302 		tpg->buffers = 3;
303 		tpg->planes = 3;
304 		tpg->vdownsampling[1] = 1;
305 		tpg->vdownsampling[2] = 1;
306 		tpg->hdownsampling[1] = 1;
307 		tpg->hdownsampling[2] = 1;
308 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
309 		break;
310 	case V4L2_PIX_FMT_NV24:
311 	case V4L2_PIX_FMT_NV42:
312 		tpg->vdownsampling[1] = 1;
313 		tpg->hdownsampling[1] = 1;
314 		tpg->planes = 2;
315 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
316 		break;
317 	case V4L2_PIX_FMT_YUYV:
318 	case V4L2_PIX_FMT_UYVY:
319 	case V4L2_PIX_FMT_YVYU:
320 	case V4L2_PIX_FMT_VYUY:
321 		tpg->hmask[0] = ~1;
322 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
323 		break;
324 	case V4L2_PIX_FMT_HSV24:
325 	case V4L2_PIX_FMT_HSV32:
326 		tpg->color_enc = TGP_COLOR_ENC_HSV;
327 		break;
328 	default:
329 		return false;
330 	}
331 
332 	switch (fourcc) {
333 	case V4L2_PIX_FMT_GREY:
334 	case V4L2_PIX_FMT_RGB332:
335 		tpg->twopixelsize[0] = 2;
336 		break;
337 	case V4L2_PIX_FMT_RGB565:
338 	case V4L2_PIX_FMT_RGB565X:
339 	case V4L2_PIX_FMT_RGB444:
340 	case V4L2_PIX_FMT_XRGB444:
341 	case V4L2_PIX_FMT_ARGB444:
342 	case V4L2_PIX_FMT_RGB555:
343 	case V4L2_PIX_FMT_XRGB555:
344 	case V4L2_PIX_FMT_ARGB555:
345 	case V4L2_PIX_FMT_RGB555X:
346 	case V4L2_PIX_FMT_XRGB555X:
347 	case V4L2_PIX_FMT_ARGB555X:
348 	case V4L2_PIX_FMT_YUYV:
349 	case V4L2_PIX_FMT_UYVY:
350 	case V4L2_PIX_FMT_YVYU:
351 	case V4L2_PIX_FMT_VYUY:
352 	case V4L2_PIX_FMT_YUV444:
353 	case V4L2_PIX_FMT_YUV555:
354 	case V4L2_PIX_FMT_YUV565:
355 	case V4L2_PIX_FMT_Y16:
356 	case V4L2_PIX_FMT_Y16_BE:
357 		tpg->twopixelsize[0] = 2 * 2;
358 		break;
359 	case V4L2_PIX_FMT_RGB24:
360 	case V4L2_PIX_FMT_BGR24:
361 	case V4L2_PIX_FMT_HSV24:
362 		tpg->twopixelsize[0] = 2 * 3;
363 		break;
364 	case V4L2_PIX_FMT_BGR666:
365 	case V4L2_PIX_FMT_RGB32:
366 	case V4L2_PIX_FMT_BGR32:
367 	case V4L2_PIX_FMT_XRGB32:
368 	case V4L2_PIX_FMT_XBGR32:
369 	case V4L2_PIX_FMT_ARGB32:
370 	case V4L2_PIX_FMT_ABGR32:
371 	case V4L2_PIX_FMT_YUV32:
372 	case V4L2_PIX_FMT_HSV32:
373 		tpg->twopixelsize[0] = 2 * 4;
374 		break;
375 	case V4L2_PIX_FMT_NV12:
376 	case V4L2_PIX_FMT_NV21:
377 	case V4L2_PIX_FMT_NV12M:
378 	case V4L2_PIX_FMT_NV21M:
379 	case V4L2_PIX_FMT_NV16:
380 	case V4L2_PIX_FMT_NV61:
381 	case V4L2_PIX_FMT_NV16M:
382 	case V4L2_PIX_FMT_NV61M:
383 	case V4L2_PIX_FMT_SBGGR8:
384 	case V4L2_PIX_FMT_SGBRG8:
385 	case V4L2_PIX_FMT_SGRBG8:
386 	case V4L2_PIX_FMT_SRGGB8:
387 		tpg->twopixelsize[0] = 2;
388 		tpg->twopixelsize[1] = 2;
389 		break;
390 	case V4L2_PIX_FMT_SRGGB10:
391 	case V4L2_PIX_FMT_SGRBG10:
392 	case V4L2_PIX_FMT_SGBRG10:
393 	case V4L2_PIX_FMT_SBGGR10:
394 	case V4L2_PIX_FMT_SRGGB12:
395 	case V4L2_PIX_FMT_SGRBG12:
396 	case V4L2_PIX_FMT_SGBRG12:
397 	case V4L2_PIX_FMT_SBGGR12:
398 		tpg->twopixelsize[0] = 4;
399 		tpg->twopixelsize[1] = 4;
400 		break;
401 	case V4L2_PIX_FMT_YUV444M:
402 	case V4L2_PIX_FMT_YVU444M:
403 	case V4L2_PIX_FMT_YUV422M:
404 	case V4L2_PIX_FMT_YVU422M:
405 	case V4L2_PIX_FMT_YUV422P:
406 	case V4L2_PIX_FMT_YUV420:
407 	case V4L2_PIX_FMT_YVU420:
408 	case V4L2_PIX_FMT_YUV420M:
409 	case V4L2_PIX_FMT_YVU420M:
410 		tpg->twopixelsize[0] = 2;
411 		tpg->twopixelsize[1] = 2;
412 		tpg->twopixelsize[2] = 2;
413 		break;
414 	case V4L2_PIX_FMT_NV24:
415 	case V4L2_PIX_FMT_NV42:
416 		tpg->twopixelsize[0] = 2;
417 		tpg->twopixelsize[1] = 4;
418 		break;
419 	}
420 	return true;
421 }
422 EXPORT_SYMBOL_GPL(tpg_s_fourcc);
423 
424 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
425 		const struct v4l2_rect *compose)
426 {
427 	tpg->crop = *crop;
428 	tpg->compose = *compose;
429 	tpg->scaled_width = (tpg->src_width * tpg->compose.width +
430 				 tpg->crop.width - 1) / tpg->crop.width;
431 	tpg->scaled_width &= ~1;
432 	if (tpg->scaled_width > tpg->max_line_width)
433 		tpg->scaled_width = tpg->max_line_width;
434 	if (tpg->scaled_width < 2)
435 		tpg->scaled_width = 2;
436 	tpg->recalc_lines = true;
437 }
438 EXPORT_SYMBOL_GPL(tpg_s_crop_compose);
439 
440 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
441 		       u32 field)
442 {
443 	unsigned p;
444 
445 	tpg->src_width = width;
446 	tpg->src_height = height;
447 	tpg->field = field;
448 	tpg->buf_height = height;
449 	if (V4L2_FIELD_HAS_T_OR_B(field))
450 		tpg->buf_height /= 2;
451 	tpg->scaled_width = width;
452 	tpg->crop.top = tpg->crop.left = 0;
453 	tpg->crop.width = width;
454 	tpg->crop.height = height;
455 	tpg->compose.top = tpg->compose.left = 0;
456 	tpg->compose.width = width;
457 	tpg->compose.height = tpg->buf_height;
458 	for (p = 0; p < tpg->planes; p++)
459 		tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
460 				       (2 * tpg->hdownsampling[p]);
461 	tpg->recalc_square_border = true;
462 }
463 EXPORT_SYMBOL_GPL(tpg_reset_source);
464 
465 static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
466 {
467 	switch (tpg->pattern) {
468 	case TPG_PAT_BLACK:
469 		return TPG_COLOR_100_WHITE;
470 	case TPG_PAT_CSC_COLORBAR:
471 		return TPG_COLOR_CSC_BLACK;
472 	default:
473 		return TPG_COLOR_100_BLACK;
474 	}
475 }
476 
477 static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
478 {
479 	switch (tpg->pattern) {
480 	case TPG_PAT_75_COLORBAR:
481 	case TPG_PAT_CSC_COLORBAR:
482 		return TPG_COLOR_CSC_WHITE;
483 	case TPG_PAT_BLACK:
484 		return TPG_COLOR_100_BLACK;
485 	default:
486 		return TPG_COLOR_100_WHITE;
487 	}
488 }
489 
490 static inline int rec709_to_linear(int v)
491 {
492 	v = clamp(v, 0, 0xff0);
493 	return tpg_rec709_to_linear[v];
494 }
495 
496 static inline int linear_to_rec709(int v)
497 {
498 	v = clamp(v, 0, 0xff0);
499 	return tpg_linear_to_rec709[v];
500 }
501 
502 static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
503 			   int *h, int *s, int *v)
504 {
505 	int max_rgb, min_rgb, diff_rgb;
506 	int aux;
507 	int third;
508 	int third_size;
509 
510 	r >>= 4;
511 	g >>= 4;
512 	b >>= 4;
513 
514 	/* Value */
515 	max_rgb = max3(r, g, b);
516 	*v = max_rgb;
517 	if (!max_rgb) {
518 		*h = 0;
519 		*s = 0;
520 		return;
521 	}
522 
523 	/* Saturation */
524 	min_rgb = min3(r, g, b);
525 	diff_rgb = max_rgb - min_rgb;
526 	aux = 255 * diff_rgb;
527 	aux += max_rgb / 2;
528 	aux /= max_rgb;
529 	*s = aux;
530 	if (!aux) {
531 		*h = 0;
532 		return;
533 	}
534 
535 	third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85;
536 
537 	/* Hue */
538 	if (max_rgb == r) {
539 		aux =  g - b;
540 		third = 0;
541 	} else if (max_rgb == g) {
542 		aux =  b - r;
543 		third = third_size;
544 	} else {
545 		aux =  r - g;
546 		third = third_size * 2;
547 	}
548 
549 	aux *= third_size / 2;
550 	aux += diff_rgb / 2;
551 	aux /= diff_rgb;
552 	aux += third;
553 
554 	/* Clamp Hue */
555 	if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) {
556 		if (aux < 0)
557 			aux += 180;
558 		else if (aux > 180)
559 			aux -= 180;
560 	} else {
561 		aux = aux & 0xff;
562 	}
563 
564 	*h = aux;
565 }
566 
567 static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
568 			int y_offset, int *y, int *cb, int *cr)
569 {
570 	*y  = ((m[0][0] * r + m[0][1] * g + m[0][2] * b) >> 16) + (y_offset << 4);
571 	*cb = ((m[1][0] * r + m[1][1] * g + m[1][2] * b) >> 16) + (128 << 4);
572 	*cr = ((m[2][0] * r + m[2][1] * g + m[2][2] * b) >> 16) + (128 << 4);
573 }
574 
575 static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
576 			   int *y, int *cb, int *cr)
577 {
578 #define COEFF(v, r) ((int)(0.5 + (v) * (r) * 256.0))
579 
580 	static const int bt601[3][3] = {
581 		{ COEFF(0.299, 219),   COEFF(0.587, 219),   COEFF(0.114, 219)   },
582 		{ COEFF(-0.1687, 224), COEFF(-0.3313, 224), COEFF(0.5, 224)     },
583 		{ COEFF(0.5, 224),     COEFF(-0.4187, 224), COEFF(-0.0813, 224) },
584 	};
585 	static const int bt601_full[3][3] = {
586 		{ COEFF(0.299, 255),   COEFF(0.587, 255),   COEFF(0.114, 255)   },
587 		{ COEFF(-0.1687, 255), COEFF(-0.3313, 255), COEFF(0.5, 255)     },
588 		{ COEFF(0.5, 255),     COEFF(-0.4187, 255), COEFF(-0.0813, 255) },
589 	};
590 	static const int rec709[3][3] = {
591 		{ COEFF(0.2126, 219),  COEFF(0.7152, 219),  COEFF(0.0722, 219)  },
592 		{ COEFF(-0.1146, 224), COEFF(-0.3854, 224), COEFF(0.5, 224)     },
593 		{ COEFF(0.5, 224),     COEFF(-0.4542, 224), COEFF(-0.0458, 224) },
594 	};
595 	static const int rec709_full[3][3] = {
596 		{ COEFF(0.2126, 255),  COEFF(0.7152, 255),  COEFF(0.0722, 255)  },
597 		{ COEFF(-0.1146, 255), COEFF(-0.3854, 255), COEFF(0.5, 255)     },
598 		{ COEFF(0.5, 255),     COEFF(-0.4542, 255), COEFF(-0.0458, 255) },
599 	};
600 	static const int smpte240m[3][3] = {
601 		{ COEFF(0.212, 219),  COEFF(0.701, 219),  COEFF(0.087, 219)  },
602 		{ COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224)    },
603 		{ COEFF(0.5, 224),    COEFF(-0.445, 224), COEFF(-0.055, 224) },
604 	};
605 	static const int smpte240m_full[3][3] = {
606 		{ COEFF(0.212, 255),  COEFF(0.701, 255),  COEFF(0.087, 255)  },
607 		{ COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255)    },
608 		{ COEFF(0.5, 255),    COEFF(-0.445, 255), COEFF(-0.055, 255) },
609 	};
610 	static const int bt2020[3][3] = {
611 		{ COEFF(0.2627, 219),  COEFF(0.6780, 219),  COEFF(0.0593, 219)  },
612 		{ COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224)     },
613 		{ COEFF(0.5, 224),     COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
614 	};
615 	static const int bt2020_full[3][3] = {
616 		{ COEFF(0.2627, 255),  COEFF(0.6780, 255),  COEFF(0.0593, 255)  },
617 		{ COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255)     },
618 		{ COEFF(0.5, 255),     COEFF(-0.4698, 255), COEFF(-0.0402, 255) },
619 	};
620 	static const int bt2020c[4] = {
621 		COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224),
622 		COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224),
623 	};
624 	static const int bt2020c_full[4] = {
625 		COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255),
626 		COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255),
627 	};
628 
629 	bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
630 	unsigned y_offset = full ? 0 : 16;
631 	int lin_y, yc;
632 
633 	switch (tpg->real_ycbcr_enc) {
634 	case V4L2_YCBCR_ENC_601:
635 		rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr);
636 		break;
637 	case V4L2_YCBCR_ENC_XV601:
638 		/* Ignore quantization range, there is only one possible
639 		 * Y'CbCr encoding. */
640 		rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr);
641 		break;
642 	case V4L2_YCBCR_ENC_XV709:
643 		/* Ignore quantization range, there is only one possible
644 		 * Y'CbCr encoding. */
645 		rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr);
646 		break;
647 	case V4L2_YCBCR_ENC_BT2020:
648 		rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr);
649 		break;
650 	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
651 		lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) +
652 			 COEFF(0.6780, 255) * rec709_to_linear(g) +
653 			 COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16;
654 		yc = linear_to_rec709(lin_y);
655 		*y = full ? yc : (yc * 219) / 255 + (16 << 4);
656 		if (b <= yc)
657 			*cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4);
658 		else
659 			*cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4);
660 		if (r <= yc)
661 			*cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4);
662 		else
663 			*cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4);
664 		break;
665 	case V4L2_YCBCR_ENC_SMPTE240M:
666 		rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr);
667 		break;
668 	case V4L2_YCBCR_ENC_709:
669 	default:
670 		rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr);
671 		break;
672 	}
673 }
674 
675 static void ycbcr2rgb(const int m[3][3], int y, int cb, int cr,
676 			int y_offset, int *r, int *g, int *b)
677 {
678 	y -= y_offset << 4;
679 	cb -= 128 << 4;
680 	cr -= 128 << 4;
681 	*r = m[0][0] * y + m[0][1] * cb + m[0][2] * cr;
682 	*g = m[1][0] * y + m[1][1] * cb + m[1][2] * cr;
683 	*b = m[2][0] * y + m[2][1] * cb + m[2][2] * cr;
684 	*r = clamp(*r >> 12, 0, 0xff0);
685 	*g = clamp(*g >> 12, 0, 0xff0);
686 	*b = clamp(*b >> 12, 0, 0xff0);
687 }
688 
689 static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
690 			   int *r, int *g, int *b)
691 {
692 #undef COEFF
693 #define COEFF(v, r) ((int)(0.5 + (v) * ((255.0 * 255.0 * 16.0) / (r))))
694 	static const int bt601[3][3] = {
695 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.4020, 224)  },
696 		{ COEFF(1, 219), COEFF(-0.3441, 224), COEFF(-0.7141, 224) },
697 		{ COEFF(1, 219), COEFF(1.7720, 224),  COEFF(0, 224)       },
698 	};
699 	static const int bt601_full[3][3] = {
700 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.4020, 255)  },
701 		{ COEFF(1, 255), COEFF(-0.3441, 255), COEFF(-0.7141, 255) },
702 		{ COEFF(1, 255), COEFF(1.7720, 255),  COEFF(0, 255)       },
703 	};
704 	static const int rec709[3][3] = {
705 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.5748, 224)  },
706 		{ COEFF(1, 219), COEFF(-0.1873, 224), COEFF(-0.4681, 224) },
707 		{ COEFF(1, 219), COEFF(1.8556, 224),  COEFF(0, 224)       },
708 	};
709 	static const int rec709_full[3][3] = {
710 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.5748, 255)  },
711 		{ COEFF(1, 255), COEFF(-0.1873, 255), COEFF(-0.4681, 255) },
712 		{ COEFF(1, 255), COEFF(1.8556, 255),  COEFF(0, 255)       },
713 	};
714 	static const int smpte240m[3][3] = {
715 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.5756, 224)  },
716 		{ COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) },
717 		{ COEFF(1, 219), COEFF(1.8270, 224),  COEFF(0, 224)       },
718 	};
719 	static const int smpte240m_full[3][3] = {
720 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.5756, 255)  },
721 		{ COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) },
722 		{ COEFF(1, 255), COEFF(1.8270, 255),  COEFF(0, 255)       },
723 	};
724 	static const int bt2020[3][3] = {
725 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.4746, 224)  },
726 		{ COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) },
727 		{ COEFF(1, 219), COEFF(1.8814, 224),  COEFF(0, 224)       },
728 	};
729 	static const int bt2020_full[3][3] = {
730 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.4746, 255)  },
731 		{ COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) },
732 		{ COEFF(1, 255), COEFF(1.8814, 255),  COEFF(0, 255)       },
733 	};
734 	static const int bt2020c[4] = {
735 		COEFF(1.9404, 224), COEFF(1.5816, 224),
736 		COEFF(1.7184, 224), COEFF(0.9936, 224),
737 	};
738 	static const int bt2020c_full[4] = {
739 		COEFF(1.9404, 255), COEFF(1.5816, 255),
740 		COEFF(1.7184, 255), COEFF(0.9936, 255),
741 	};
742 
743 	bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
744 	unsigned y_offset = full ? 0 : 16;
745 	int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219);
746 	int lin_r, lin_g, lin_b, lin_y;
747 
748 	switch (tpg->real_ycbcr_enc) {
749 	case V4L2_YCBCR_ENC_601:
750 		ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b);
751 		break;
752 	case V4L2_YCBCR_ENC_XV601:
753 		/* Ignore quantization range, there is only one possible
754 		 * Y'CbCr encoding. */
755 		ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b);
756 		break;
757 	case V4L2_YCBCR_ENC_XV709:
758 		/* Ignore quantization range, there is only one possible
759 		 * Y'CbCr encoding. */
760 		ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b);
761 		break;
762 	case V4L2_YCBCR_ENC_BT2020:
763 		ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b);
764 		break;
765 	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
766 		y -= full ? 0 : 16 << 4;
767 		cb -= 128 << 4;
768 		cr -= 128 << 4;
769 
770 		if (cb <= 0)
771 			*b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb;
772 		else
773 			*b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb;
774 		*b = *b >> 12;
775 		if (cr <= 0)
776 			*r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr;
777 		else
778 			*r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr;
779 		*r = *r >> 12;
780 		lin_r = rec709_to_linear(*r);
781 		lin_b = rec709_to_linear(*b);
782 		lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219));
783 
784 		lin_g = COEFF(1.0 / 0.6780, 255) * lin_y -
785 			COEFF(0.2627 / 0.6780, 255) * lin_r -
786 			COEFF(0.0593 / 0.6780, 255) * lin_b;
787 		*g = linear_to_rec709(lin_g >> 12);
788 		break;
789 	case V4L2_YCBCR_ENC_SMPTE240M:
790 		ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b);
791 		break;
792 	case V4L2_YCBCR_ENC_709:
793 	default:
794 		ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b);
795 		break;
796 	}
797 }
798 
799 /* precalculate color bar values to speed up rendering */
800 static void precalculate_color(struct tpg_data *tpg, int k)
801 {
802 	int col = k;
803 	int r = tpg_colors[col].r;
804 	int g = tpg_colors[col].g;
805 	int b = tpg_colors[col].b;
806 	int y, cb, cr;
807 	bool ycbcr_valid = false;
808 
809 	if (k == TPG_COLOR_TEXTBG) {
810 		col = tpg_get_textbg_color(tpg);
811 
812 		r = tpg_colors[col].r;
813 		g = tpg_colors[col].g;
814 		b = tpg_colors[col].b;
815 	} else if (k == TPG_COLOR_TEXTFG) {
816 		col = tpg_get_textfg_color(tpg);
817 
818 		r = tpg_colors[col].r;
819 		g = tpg_colors[col].g;
820 		b = tpg_colors[col].b;
821 	} else if (tpg->pattern == TPG_PAT_NOISE) {
822 		r = g = b = prandom_u32_max(256);
823 	} else if (k == TPG_COLOR_RANDOM) {
824 		r = g = b = tpg->qual_offset + prandom_u32_max(196);
825 	} else if (k >= TPG_COLOR_RAMP) {
826 		r = g = b = k - TPG_COLOR_RAMP;
827 	}
828 
829 	if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
830 		r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
831 		g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
832 		b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
833 	} else {
834 		r <<= 4;
835 		g <<= 4;
836 		b <<= 4;
837 	}
838 
839 	if (tpg->qual == TPG_QUAL_GRAY ||
840 	    tpg->color_enc ==  TGP_COLOR_ENC_LUMA) {
841 		/* Rec. 709 Luma function */
842 		/* (0.2126, 0.7152, 0.0722) * (255 * 256) */
843 		r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
844 	}
845 
846 	/*
847 	 * The assumption is that the RGB output is always full range,
848 	 * so only if the rgb_range overrides the 'real' rgb range do
849 	 * we need to convert the RGB values.
850 	 *
851 	 * Remember that r, g and b are still in the 0 - 0xff0 range.
852 	 */
853 	if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
854 	    tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL &&
855 	    tpg->color_enc == TGP_COLOR_ENC_RGB) {
856 		/*
857 		 * Convert from full range (which is what r, g and b are)
858 		 * to limited range (which is the 'real' RGB range), which
859 		 * is then interpreted as full range.
860 		 */
861 		r = (r * 219) / 255 + (16 << 4);
862 		g = (g * 219) / 255 + (16 << 4);
863 		b = (b * 219) / 255 + (16 << 4);
864 	} else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
865 		   tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
866 		   tpg->color_enc == TGP_COLOR_ENC_RGB) {
867 
868 		/*
869 		 * Clamp r, g and b to the limited range and convert to full
870 		 * range since that's what we deliver.
871 		 */
872 		r = clamp(r, 16 << 4, 235 << 4);
873 		g = clamp(g, 16 << 4, 235 << 4);
874 		b = clamp(b, 16 << 4, 235 << 4);
875 		r = (r - (16 << 4)) * 255 / 219;
876 		g = (g - (16 << 4)) * 255 / 219;
877 		b = (b - (16 << 4)) * 255 / 219;
878 	}
879 
880 	if ((tpg->brightness != 128 || tpg->contrast != 128 ||
881 	     tpg->saturation != 128 || tpg->hue) &&
882 	    tpg->color_enc != TGP_COLOR_ENC_LUMA) {
883 		/* Implement these operations */
884 		int tmp_cb, tmp_cr;
885 
886 		/* First convert to YCbCr */
887 
888 		color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
889 
890 		y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
891 		y += (tpg->brightness << 4) - (128 << 4);
892 
893 		cb -= 128 << 4;
894 		cr -= 128 << 4;
895 		tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
896 		tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
897 
898 		cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
899 		cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
900 		if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
901 			ycbcr_valid = true;
902 		else
903 			ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
904 	} else if ((tpg->brightness != 128 || tpg->contrast != 128) &&
905 		   tpg->color_enc == TGP_COLOR_ENC_LUMA) {
906 		r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128;
907 		r += (tpg->brightness << 4) - (128 << 4);
908 	}
909 
910 	switch (tpg->color_enc) {
911 	case TGP_COLOR_ENC_HSV:
912 	{
913 		int h, s, v;
914 
915 		color_to_hsv(tpg, r, g, b, &h, &s, &v);
916 		tpg->colors[k][0] = h;
917 		tpg->colors[k][1] = s;
918 		tpg->colors[k][2] = v;
919 		break;
920 	}
921 	case TGP_COLOR_ENC_YCBCR:
922 	{
923 		/* Convert to YCbCr */
924 		if (!ycbcr_valid)
925 			color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
926 
927 		y >>= 4;
928 		cb >>= 4;
929 		cr >>= 4;
930 		/*
931 		 * XV601/709 use the header/footer margins to encode R', G'
932 		 * and B' values outside the range [0-1]. So do not clamp
933 		 * XV601/709 values.
934 		 */
935 		if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE &&
936 		    tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV601 &&
937 		    tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV709) {
938 			y = clamp(y, 16, 235);
939 			cb = clamp(cb, 16, 240);
940 			cr = clamp(cr, 16, 240);
941 		} else {
942 			y = clamp(y, 1, 254);
943 			cb = clamp(cb, 1, 254);
944 			cr = clamp(cr, 1, 254);
945 		}
946 		switch (tpg->fourcc) {
947 		case V4L2_PIX_FMT_YUV444:
948 			y >>= 4;
949 			cb >>= 4;
950 			cr >>= 4;
951 			break;
952 		case V4L2_PIX_FMT_YUV555:
953 			y >>= 3;
954 			cb >>= 3;
955 			cr >>= 3;
956 			break;
957 		case V4L2_PIX_FMT_YUV565:
958 			y >>= 3;
959 			cb >>= 2;
960 			cr >>= 3;
961 			break;
962 		}
963 		tpg->colors[k][0] = y;
964 		tpg->colors[k][1] = cb;
965 		tpg->colors[k][2] = cr;
966 		break;
967 	}
968 	case TGP_COLOR_ENC_LUMA:
969 	{
970 		tpg->colors[k][0] = r >> 4;
971 		break;
972 	}
973 	case TGP_COLOR_ENC_RGB:
974 	{
975 		if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
976 			r = (r * 219) / 255 + (16 << 4);
977 			g = (g * 219) / 255 + (16 << 4);
978 			b = (b * 219) / 255 + (16 << 4);
979 		}
980 		switch (tpg->fourcc) {
981 		case V4L2_PIX_FMT_RGB332:
982 			r >>= 9;
983 			g >>= 9;
984 			b >>= 10;
985 			break;
986 		case V4L2_PIX_FMT_RGB565:
987 		case V4L2_PIX_FMT_RGB565X:
988 			r >>= 7;
989 			g >>= 6;
990 			b >>= 7;
991 			break;
992 		case V4L2_PIX_FMT_RGB444:
993 		case V4L2_PIX_FMT_XRGB444:
994 		case V4L2_PIX_FMT_ARGB444:
995 			r >>= 8;
996 			g >>= 8;
997 			b >>= 8;
998 			break;
999 		case V4L2_PIX_FMT_RGB555:
1000 		case V4L2_PIX_FMT_XRGB555:
1001 		case V4L2_PIX_FMT_ARGB555:
1002 		case V4L2_PIX_FMT_RGB555X:
1003 		case V4L2_PIX_FMT_XRGB555X:
1004 		case V4L2_PIX_FMT_ARGB555X:
1005 			r >>= 7;
1006 			g >>= 7;
1007 			b >>= 7;
1008 			break;
1009 		case V4L2_PIX_FMT_BGR666:
1010 			r >>= 6;
1011 			g >>= 6;
1012 			b >>= 6;
1013 			break;
1014 		default:
1015 			r >>= 4;
1016 			g >>= 4;
1017 			b >>= 4;
1018 			break;
1019 		}
1020 
1021 		tpg->colors[k][0] = r;
1022 		tpg->colors[k][1] = g;
1023 		tpg->colors[k][2] = b;
1024 		break;
1025 	}
1026 	}
1027 }
1028 
1029 static void tpg_precalculate_colors(struct tpg_data *tpg)
1030 {
1031 	int k;
1032 
1033 	for (k = 0; k < TPG_COLOR_MAX; k++)
1034 		precalculate_color(tpg, k);
1035 }
1036 
1037 /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
1038 static void gen_twopix(struct tpg_data *tpg,
1039 		u8 buf[TPG_MAX_PLANES][8], int color, bool odd)
1040 {
1041 	unsigned offset = odd * tpg->twopixelsize[0] / 2;
1042 	u8 alpha = tpg->alpha_component;
1043 	u8 r_y_h, g_u_s, b_v;
1044 
1045 	if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
1046 				   color != TPG_COLOR_100_RED &&
1047 				   color != TPG_COLOR_75_RED)
1048 		alpha = 0;
1049 	if (color == TPG_COLOR_RANDOM)
1050 		precalculate_color(tpg, color);
1051 	r_y_h = tpg->colors[color][0]; /* R or precalculated Y, H */
1052 	g_u_s = tpg->colors[color][1]; /* G or precalculated U, V */
1053 	b_v = tpg->colors[color][2]; /* B or precalculated V */
1054 
1055 	switch (tpg->fourcc) {
1056 	case V4L2_PIX_FMT_GREY:
1057 		buf[0][offset] = r_y_h;
1058 		break;
1059 	case V4L2_PIX_FMT_Y16:
1060 		/*
1061 		 * Ideally both bytes should be set to r_y_h, but then you won't
1062 		 * be able to detect endian problems. So keep it 0 except for
1063 		 * the corner case where r_y_h is 0xff so white really will be
1064 		 * white (0xffff).
1065 		 */
1066 		buf[0][offset] = r_y_h == 0xff ? r_y_h : 0;
1067 		buf[0][offset+1] = r_y_h;
1068 		break;
1069 	case V4L2_PIX_FMT_Y16_BE:
1070 		/* See comment for V4L2_PIX_FMT_Y16 above */
1071 		buf[0][offset] = r_y_h;
1072 		buf[0][offset+1] = r_y_h == 0xff ? r_y_h : 0;
1073 		break;
1074 	case V4L2_PIX_FMT_YUV422M:
1075 	case V4L2_PIX_FMT_YUV422P:
1076 	case V4L2_PIX_FMT_YUV420:
1077 	case V4L2_PIX_FMT_YUV420M:
1078 		buf[0][offset] = r_y_h;
1079 		if (odd) {
1080 			buf[1][0] = (buf[1][0] + g_u_s) / 2;
1081 			buf[2][0] = (buf[2][0] + b_v) / 2;
1082 			buf[1][1] = buf[1][0];
1083 			buf[2][1] = buf[2][0];
1084 			break;
1085 		}
1086 		buf[1][0] = g_u_s;
1087 		buf[2][0] = b_v;
1088 		break;
1089 	case V4L2_PIX_FMT_YVU422M:
1090 	case V4L2_PIX_FMT_YVU420:
1091 	case V4L2_PIX_FMT_YVU420M:
1092 		buf[0][offset] = r_y_h;
1093 		if (odd) {
1094 			buf[1][0] = (buf[1][0] + b_v) / 2;
1095 			buf[2][0] = (buf[2][0] + g_u_s) / 2;
1096 			buf[1][1] = buf[1][0];
1097 			buf[2][1] = buf[2][0];
1098 			break;
1099 		}
1100 		buf[1][0] = b_v;
1101 		buf[2][0] = g_u_s;
1102 		break;
1103 
1104 	case V4L2_PIX_FMT_NV12:
1105 	case V4L2_PIX_FMT_NV12M:
1106 	case V4L2_PIX_FMT_NV16:
1107 	case V4L2_PIX_FMT_NV16M:
1108 		buf[0][offset] = r_y_h;
1109 		if (odd) {
1110 			buf[1][0] = (buf[1][0] + g_u_s) / 2;
1111 			buf[1][1] = (buf[1][1] + b_v) / 2;
1112 			break;
1113 		}
1114 		buf[1][0] = g_u_s;
1115 		buf[1][1] = b_v;
1116 		break;
1117 	case V4L2_PIX_FMT_NV21:
1118 	case V4L2_PIX_FMT_NV21M:
1119 	case V4L2_PIX_FMT_NV61:
1120 	case V4L2_PIX_FMT_NV61M:
1121 		buf[0][offset] = r_y_h;
1122 		if (odd) {
1123 			buf[1][0] = (buf[1][0] + b_v) / 2;
1124 			buf[1][1] = (buf[1][1] + g_u_s) / 2;
1125 			break;
1126 		}
1127 		buf[1][0] = b_v;
1128 		buf[1][1] = g_u_s;
1129 		break;
1130 
1131 	case V4L2_PIX_FMT_YUV444M:
1132 		buf[0][offset] = r_y_h;
1133 		buf[1][offset] = g_u_s;
1134 		buf[2][offset] = b_v;
1135 		break;
1136 
1137 	case V4L2_PIX_FMT_YVU444M:
1138 		buf[0][offset] = r_y_h;
1139 		buf[1][offset] = b_v;
1140 		buf[2][offset] = g_u_s;
1141 		break;
1142 
1143 	case V4L2_PIX_FMT_NV24:
1144 		buf[0][offset] = r_y_h;
1145 		buf[1][2 * offset] = g_u_s;
1146 		buf[1][2 * offset + 1] = b_v;
1147 		break;
1148 
1149 	case V4L2_PIX_FMT_NV42:
1150 		buf[0][offset] = r_y_h;
1151 		buf[1][2 * offset] = b_v;
1152 		buf[1][2 * offset + 1] = g_u_s;
1153 		break;
1154 
1155 	case V4L2_PIX_FMT_YUYV:
1156 		buf[0][offset] = r_y_h;
1157 		if (odd) {
1158 			buf[0][1] = (buf[0][1] + g_u_s) / 2;
1159 			buf[0][3] = (buf[0][3] + b_v) / 2;
1160 			break;
1161 		}
1162 		buf[0][1] = g_u_s;
1163 		buf[0][3] = b_v;
1164 		break;
1165 	case V4L2_PIX_FMT_UYVY:
1166 		buf[0][offset + 1] = r_y_h;
1167 		if (odd) {
1168 			buf[0][0] = (buf[0][0] + g_u_s) / 2;
1169 			buf[0][2] = (buf[0][2] + b_v) / 2;
1170 			break;
1171 		}
1172 		buf[0][0] = g_u_s;
1173 		buf[0][2] = b_v;
1174 		break;
1175 	case V4L2_PIX_FMT_YVYU:
1176 		buf[0][offset] = r_y_h;
1177 		if (odd) {
1178 			buf[0][1] = (buf[0][1] + b_v) / 2;
1179 			buf[0][3] = (buf[0][3] + g_u_s) / 2;
1180 			break;
1181 		}
1182 		buf[0][1] = b_v;
1183 		buf[0][3] = g_u_s;
1184 		break;
1185 	case V4L2_PIX_FMT_VYUY:
1186 		buf[0][offset + 1] = r_y_h;
1187 		if (odd) {
1188 			buf[0][0] = (buf[0][0] + b_v) / 2;
1189 			buf[0][2] = (buf[0][2] + g_u_s) / 2;
1190 			break;
1191 		}
1192 		buf[0][0] = b_v;
1193 		buf[0][2] = g_u_s;
1194 		break;
1195 	case V4L2_PIX_FMT_RGB332:
1196 		buf[0][offset] = (r_y_h << 5) | (g_u_s << 2) | b_v;
1197 		break;
1198 	case V4L2_PIX_FMT_YUV565:
1199 	case V4L2_PIX_FMT_RGB565:
1200 		buf[0][offset] = (g_u_s << 5) | b_v;
1201 		buf[0][offset + 1] = (r_y_h << 3) | (g_u_s >> 3);
1202 		break;
1203 	case V4L2_PIX_FMT_RGB565X:
1204 		buf[0][offset] = (r_y_h << 3) | (g_u_s >> 3);
1205 		buf[0][offset + 1] = (g_u_s << 5) | b_v;
1206 		break;
1207 	case V4L2_PIX_FMT_RGB444:
1208 	case V4L2_PIX_FMT_XRGB444:
1209 		alpha = 0;
1210 		/* fall through */
1211 	case V4L2_PIX_FMT_YUV444:
1212 	case V4L2_PIX_FMT_ARGB444:
1213 		buf[0][offset] = (g_u_s << 4) | b_v;
1214 		buf[0][offset + 1] = (alpha & 0xf0) | r_y_h;
1215 		break;
1216 	case V4L2_PIX_FMT_RGB555:
1217 	case V4L2_PIX_FMT_XRGB555:
1218 		alpha = 0;
1219 		/* fall through */
1220 	case V4L2_PIX_FMT_YUV555:
1221 	case V4L2_PIX_FMT_ARGB555:
1222 		buf[0][offset] = (g_u_s << 5) | b_v;
1223 		buf[0][offset + 1] = (alpha & 0x80) | (r_y_h << 2)
1224 						    | (g_u_s >> 3);
1225 		break;
1226 	case V4L2_PIX_FMT_RGB555X:
1227 	case V4L2_PIX_FMT_XRGB555X:
1228 		alpha = 0;
1229 		/* fall through */
1230 	case V4L2_PIX_FMT_ARGB555X:
1231 		buf[0][offset] = (alpha & 0x80) | (r_y_h << 2) | (g_u_s >> 3);
1232 		buf[0][offset + 1] = (g_u_s << 5) | b_v;
1233 		break;
1234 	case V4L2_PIX_FMT_RGB24:
1235 	case V4L2_PIX_FMT_HSV24:
1236 		buf[0][offset] = r_y_h;
1237 		buf[0][offset + 1] = g_u_s;
1238 		buf[0][offset + 2] = b_v;
1239 		break;
1240 	case V4L2_PIX_FMT_BGR24:
1241 		buf[0][offset] = b_v;
1242 		buf[0][offset + 1] = g_u_s;
1243 		buf[0][offset + 2] = r_y_h;
1244 		break;
1245 	case V4L2_PIX_FMT_BGR666:
1246 		buf[0][offset] = (b_v << 2) | (g_u_s >> 4);
1247 		buf[0][offset + 1] = (g_u_s << 4) | (r_y_h >> 2);
1248 		buf[0][offset + 2] = r_y_h << 6;
1249 		buf[0][offset + 3] = 0;
1250 		break;
1251 	case V4L2_PIX_FMT_RGB32:
1252 	case V4L2_PIX_FMT_XRGB32:
1253 	case V4L2_PIX_FMT_HSV32:
1254 		alpha = 0;
1255 		/* fall through */
1256 	case V4L2_PIX_FMT_YUV32:
1257 	case V4L2_PIX_FMT_ARGB32:
1258 		buf[0][offset] = alpha;
1259 		buf[0][offset + 1] = r_y_h;
1260 		buf[0][offset + 2] = g_u_s;
1261 		buf[0][offset + 3] = b_v;
1262 		break;
1263 	case V4L2_PIX_FMT_BGR32:
1264 	case V4L2_PIX_FMT_XBGR32:
1265 		alpha = 0;
1266 		/* fall through */
1267 	case V4L2_PIX_FMT_ABGR32:
1268 		buf[0][offset] = b_v;
1269 		buf[0][offset + 1] = g_u_s;
1270 		buf[0][offset + 2] = r_y_h;
1271 		buf[0][offset + 3] = alpha;
1272 		break;
1273 	case V4L2_PIX_FMT_SBGGR8:
1274 		buf[0][offset] = odd ? g_u_s : b_v;
1275 		buf[1][offset] = odd ? r_y_h : g_u_s;
1276 		break;
1277 	case V4L2_PIX_FMT_SGBRG8:
1278 		buf[0][offset] = odd ? b_v : g_u_s;
1279 		buf[1][offset] = odd ? g_u_s : r_y_h;
1280 		break;
1281 	case V4L2_PIX_FMT_SGRBG8:
1282 		buf[0][offset] = odd ? r_y_h : g_u_s;
1283 		buf[1][offset] = odd ? g_u_s : b_v;
1284 		break;
1285 	case V4L2_PIX_FMT_SRGGB8:
1286 		buf[0][offset] = odd ? g_u_s : r_y_h;
1287 		buf[1][offset] = odd ? b_v : g_u_s;
1288 		break;
1289 	case V4L2_PIX_FMT_SBGGR10:
1290 		buf[0][offset] = odd ? g_u_s << 2 : b_v << 2;
1291 		buf[0][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6;
1292 		buf[1][offset] = odd ? r_y_h << 2 : g_u_s << 2;
1293 		buf[1][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6;
1294 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1295 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1296 		break;
1297 	case V4L2_PIX_FMT_SGBRG10:
1298 		buf[0][offset] = odd ? b_v << 2 : g_u_s << 2;
1299 		buf[0][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6;
1300 		buf[1][offset] = odd ? g_u_s << 2 : r_y_h << 2;
1301 		buf[1][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6;
1302 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1303 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1304 		break;
1305 	case V4L2_PIX_FMT_SGRBG10:
1306 		buf[0][offset] = odd ? r_y_h << 2 : g_u_s << 2;
1307 		buf[0][offset + 1] = odd ? r_y_h >> 6 : g_u_s >> 6;
1308 		buf[1][offset] = odd ? g_u_s << 2 : b_v << 2;
1309 		buf[1][offset + 1] = odd ? g_u_s >> 6 : b_v >> 6;
1310 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1311 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1312 		break;
1313 	case V4L2_PIX_FMT_SRGGB10:
1314 		buf[0][offset] = odd ? g_u_s << 2 : r_y_h << 2;
1315 		buf[0][offset + 1] = odd ? g_u_s >> 6 : r_y_h >> 6;
1316 		buf[1][offset] = odd ? b_v << 2 : g_u_s << 2;
1317 		buf[1][offset + 1] = odd ? b_v >> 6 : g_u_s >> 6;
1318 		buf[0][offset] |= (buf[0][offset] >> 2) & 3;
1319 		buf[1][offset] |= (buf[1][offset] >> 2) & 3;
1320 		break;
1321 	case V4L2_PIX_FMT_SBGGR12:
1322 		buf[0][offset] = odd ? g_u_s << 4 : b_v << 4;
1323 		buf[0][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4;
1324 		buf[1][offset] = odd ? r_y_h << 4 : g_u_s << 4;
1325 		buf[1][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4;
1326 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1327 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1328 		break;
1329 	case V4L2_PIX_FMT_SGBRG12:
1330 		buf[0][offset] = odd ? b_v << 4 : g_u_s << 4;
1331 		buf[0][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4;
1332 		buf[1][offset] = odd ? g_u_s << 4 : r_y_h << 4;
1333 		buf[1][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4;
1334 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1335 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1336 		break;
1337 	case V4L2_PIX_FMT_SGRBG12:
1338 		buf[0][offset] = odd ? r_y_h << 4 : g_u_s << 4;
1339 		buf[0][offset + 1] = odd ? r_y_h >> 4 : g_u_s >> 4;
1340 		buf[1][offset] = odd ? g_u_s << 4 : b_v << 4;
1341 		buf[1][offset + 1] = odd ? g_u_s >> 4 : b_v >> 4;
1342 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1343 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1344 		break;
1345 	case V4L2_PIX_FMT_SRGGB12:
1346 		buf[0][offset] = odd ? g_u_s << 4 : r_y_h << 4;
1347 		buf[0][offset + 1] = odd ? g_u_s >> 4 : r_y_h >> 4;
1348 		buf[1][offset] = odd ? b_v << 4 : g_u_s << 4;
1349 		buf[1][offset + 1] = odd ? b_v >> 4 : g_u_s >> 4;
1350 		buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
1351 		buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
1352 		break;
1353 	}
1354 }
1355 
1356 unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
1357 {
1358 	switch (tpg->fourcc) {
1359 	case V4L2_PIX_FMT_SBGGR8:
1360 	case V4L2_PIX_FMT_SGBRG8:
1361 	case V4L2_PIX_FMT_SGRBG8:
1362 	case V4L2_PIX_FMT_SRGGB8:
1363 	case V4L2_PIX_FMT_SBGGR10:
1364 	case V4L2_PIX_FMT_SGBRG10:
1365 	case V4L2_PIX_FMT_SGRBG10:
1366 	case V4L2_PIX_FMT_SRGGB10:
1367 	case V4L2_PIX_FMT_SBGGR12:
1368 	case V4L2_PIX_FMT_SGBRG12:
1369 	case V4L2_PIX_FMT_SGRBG12:
1370 	case V4L2_PIX_FMT_SRGGB12:
1371 		return buf_line & 1;
1372 	default:
1373 		return 0;
1374 	}
1375 }
1376 EXPORT_SYMBOL_GPL(tpg_g_interleaved_plane);
1377 
1378 /* Return how many pattern lines are used by the current pattern. */
1379 static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
1380 {
1381 	switch (tpg->pattern) {
1382 	case TPG_PAT_CHECKERS_16X16:
1383 	case TPG_PAT_CHECKERS_2X2:
1384 	case TPG_PAT_CHECKERS_1X1:
1385 	case TPG_PAT_COLOR_CHECKERS_2X2:
1386 	case TPG_PAT_COLOR_CHECKERS_1X1:
1387 	case TPG_PAT_ALTERNATING_HLINES:
1388 	case TPG_PAT_CROSS_1_PIXEL:
1389 	case TPG_PAT_CROSS_2_PIXELS:
1390 	case TPG_PAT_CROSS_10_PIXELS:
1391 		return 2;
1392 	case TPG_PAT_100_COLORSQUARES:
1393 	case TPG_PAT_100_HCOLORBAR:
1394 		return 8;
1395 	default:
1396 		return 1;
1397 	}
1398 }
1399 
1400 /* Which pattern line should be used for the given frame line. */
1401 static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
1402 {
1403 	switch (tpg->pattern) {
1404 	case TPG_PAT_CHECKERS_16X16:
1405 		return (line >> 4) & 1;
1406 	case TPG_PAT_CHECKERS_1X1:
1407 	case TPG_PAT_COLOR_CHECKERS_1X1:
1408 	case TPG_PAT_ALTERNATING_HLINES:
1409 		return line & 1;
1410 	case TPG_PAT_CHECKERS_2X2:
1411 	case TPG_PAT_COLOR_CHECKERS_2X2:
1412 		return (line & 2) >> 1;
1413 	case TPG_PAT_100_COLORSQUARES:
1414 	case TPG_PAT_100_HCOLORBAR:
1415 		return (line * 8) / tpg->src_height;
1416 	case TPG_PAT_CROSS_1_PIXEL:
1417 		return line == tpg->src_height / 2;
1418 	case TPG_PAT_CROSS_2_PIXELS:
1419 		return (line + 1) / 2 == tpg->src_height / 4;
1420 	case TPG_PAT_CROSS_10_PIXELS:
1421 		return (line + 10) / 20 == tpg->src_height / 40;
1422 	default:
1423 		return 0;
1424 	}
1425 }
1426 
1427 /*
1428  * Which color should be used for the given pattern line and X coordinate.
1429  * Note: x is in the range 0 to 2 * tpg->src_width.
1430  */
1431 static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
1432 				    unsigned pat_line, unsigned x)
1433 {
1434 	/* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code
1435 	   should be modified */
1436 	static const enum tpg_color bars[3][8] = {
1437 		/* Standard ITU-R 75% color bar sequence */
1438 		{ TPG_COLOR_CSC_WHITE,   TPG_COLOR_75_YELLOW,
1439 		  TPG_COLOR_75_CYAN,     TPG_COLOR_75_GREEN,
1440 		  TPG_COLOR_75_MAGENTA,  TPG_COLOR_75_RED,
1441 		  TPG_COLOR_75_BLUE,     TPG_COLOR_100_BLACK, },
1442 		/* Standard ITU-R 100% color bar sequence */
1443 		{ TPG_COLOR_100_WHITE,   TPG_COLOR_100_YELLOW,
1444 		  TPG_COLOR_100_CYAN,    TPG_COLOR_100_GREEN,
1445 		  TPG_COLOR_100_MAGENTA, TPG_COLOR_100_RED,
1446 		  TPG_COLOR_100_BLUE,    TPG_COLOR_100_BLACK, },
1447 		/* Color bar sequence suitable to test CSC */
1448 		{ TPG_COLOR_CSC_WHITE,   TPG_COLOR_CSC_YELLOW,
1449 		  TPG_COLOR_CSC_CYAN,    TPG_COLOR_CSC_GREEN,
1450 		  TPG_COLOR_CSC_MAGENTA, TPG_COLOR_CSC_RED,
1451 		  TPG_COLOR_CSC_BLUE,    TPG_COLOR_CSC_BLACK, },
1452 	};
1453 
1454 	switch (tpg->pattern) {
1455 	case TPG_PAT_75_COLORBAR:
1456 	case TPG_PAT_100_COLORBAR:
1457 	case TPG_PAT_CSC_COLORBAR:
1458 		return bars[tpg->pattern][((x * 8) / tpg->src_width) % 8];
1459 	case TPG_PAT_100_COLORSQUARES:
1460 		return bars[1][(pat_line + (x * 8) / tpg->src_width) % 8];
1461 	case TPG_PAT_100_HCOLORBAR:
1462 		return bars[1][pat_line];
1463 	case TPG_PAT_BLACK:
1464 		return TPG_COLOR_100_BLACK;
1465 	case TPG_PAT_WHITE:
1466 		return TPG_COLOR_100_WHITE;
1467 	case TPG_PAT_RED:
1468 		return TPG_COLOR_100_RED;
1469 	case TPG_PAT_GREEN:
1470 		return TPG_COLOR_100_GREEN;
1471 	case TPG_PAT_BLUE:
1472 		return TPG_COLOR_100_BLUE;
1473 	case TPG_PAT_CHECKERS_16X16:
1474 		return (((x >> 4) & 1) ^ (pat_line & 1)) ?
1475 			TPG_COLOR_100_BLACK : TPG_COLOR_100_WHITE;
1476 	case TPG_PAT_CHECKERS_1X1:
1477 		return ((x & 1) ^ (pat_line & 1)) ?
1478 			TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1479 	case TPG_PAT_COLOR_CHECKERS_1X1:
1480 		return ((x & 1) ^ (pat_line & 1)) ?
1481 			TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1482 	case TPG_PAT_CHECKERS_2X2:
1483 		return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1484 			TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1485 	case TPG_PAT_COLOR_CHECKERS_2X2:
1486 		return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1487 			TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1488 	case TPG_PAT_ALTERNATING_HLINES:
1489 		return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1490 	case TPG_PAT_ALTERNATING_VLINES:
1491 		return (x & 1) ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1492 	case TPG_PAT_CROSS_1_PIXEL:
1493 		if (pat_line || (x % tpg->src_width) == tpg->src_width / 2)
1494 			return TPG_COLOR_100_BLACK;
1495 		return TPG_COLOR_100_WHITE;
1496 	case TPG_PAT_CROSS_2_PIXELS:
1497 		if (pat_line || ((x % tpg->src_width) + 1) / 2 == tpg->src_width / 4)
1498 			return TPG_COLOR_100_BLACK;
1499 		return TPG_COLOR_100_WHITE;
1500 	case TPG_PAT_CROSS_10_PIXELS:
1501 		if (pat_line || ((x % tpg->src_width) + 10) / 20 == tpg->src_width / 40)
1502 			return TPG_COLOR_100_BLACK;
1503 		return TPG_COLOR_100_WHITE;
1504 	case TPG_PAT_GRAY_RAMP:
1505 		return TPG_COLOR_RAMP + ((x % tpg->src_width) * 256) / tpg->src_width;
1506 	default:
1507 		return TPG_COLOR_100_RED;
1508 	}
1509 }
1510 
1511 /*
1512  * Given the pixel aspect ratio and video aspect ratio calculate the
1513  * coordinates of a centered square and the coordinates of the border of
1514  * the active video area. The coordinates are relative to the source
1515  * frame rectangle.
1516  */
1517 static void tpg_calculate_square_border(struct tpg_data *tpg)
1518 {
1519 	unsigned w = tpg->src_width;
1520 	unsigned h = tpg->src_height;
1521 	unsigned sq_w, sq_h;
1522 
1523 	sq_w = (w * 2 / 5) & ~1;
1524 	if (((w - sq_w) / 2) & 1)
1525 		sq_w += 2;
1526 	sq_h = sq_w;
1527 	tpg->square.width = sq_w;
1528 	if (tpg->vid_aspect == TPG_VIDEO_ASPECT_16X9_ANAMORPHIC) {
1529 		unsigned ana_sq_w = (sq_w / 4) * 3;
1530 
1531 		if (((w - ana_sq_w) / 2) & 1)
1532 			ana_sq_w += 2;
1533 		tpg->square.width = ana_sq_w;
1534 	}
1535 	tpg->square.left = (w - tpg->square.width) / 2;
1536 	if (tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC)
1537 		sq_h = sq_w * 10 / 11;
1538 	else if (tpg->pix_aspect == TPG_PIXEL_ASPECT_PAL)
1539 		sq_h = sq_w * 59 / 54;
1540 	tpg->square.height = sq_h;
1541 	tpg->square.top = (h - sq_h) / 2;
1542 	tpg->border.left = 0;
1543 	tpg->border.width = w;
1544 	tpg->border.top = 0;
1545 	tpg->border.height = h;
1546 	switch (tpg->vid_aspect) {
1547 	case TPG_VIDEO_ASPECT_4X3:
1548 		if (tpg->pix_aspect)
1549 			return;
1550 		if (3 * w >= 4 * h) {
1551 			tpg->border.width = ((4 * h) / 3) & ~1;
1552 			if (((w - tpg->border.width) / 2) & ~1)
1553 				tpg->border.width -= 2;
1554 			tpg->border.left = (w - tpg->border.width) / 2;
1555 			break;
1556 		}
1557 		tpg->border.height = ((3 * w) / 4) & ~1;
1558 		tpg->border.top = (h - tpg->border.height) / 2;
1559 		break;
1560 	case TPG_VIDEO_ASPECT_14X9_CENTRE:
1561 		if (tpg->pix_aspect) {
1562 			tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 420 : 506;
1563 			tpg->border.top = (h - tpg->border.height) / 2;
1564 			break;
1565 		}
1566 		if (9 * w >= 14 * h) {
1567 			tpg->border.width = ((14 * h) / 9) & ~1;
1568 			if (((w - tpg->border.width) / 2) & ~1)
1569 				tpg->border.width -= 2;
1570 			tpg->border.left = (w - tpg->border.width) / 2;
1571 			break;
1572 		}
1573 		tpg->border.height = ((9 * w) / 14) & ~1;
1574 		tpg->border.top = (h - tpg->border.height) / 2;
1575 		break;
1576 	case TPG_VIDEO_ASPECT_16X9_CENTRE:
1577 		if (tpg->pix_aspect) {
1578 			tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 368 : 442;
1579 			tpg->border.top = (h - tpg->border.height) / 2;
1580 			break;
1581 		}
1582 		if (9 * w >= 16 * h) {
1583 			tpg->border.width = ((16 * h) / 9) & ~1;
1584 			if (((w - tpg->border.width) / 2) & ~1)
1585 				tpg->border.width -= 2;
1586 			tpg->border.left = (w - tpg->border.width) / 2;
1587 			break;
1588 		}
1589 		tpg->border.height = ((9 * w) / 16) & ~1;
1590 		tpg->border.top = (h - tpg->border.height) / 2;
1591 		break;
1592 	default:
1593 		break;
1594 	}
1595 }
1596 
1597 static void tpg_precalculate_line(struct tpg_data *tpg)
1598 {
1599 	enum tpg_color contrast;
1600 	u8 pix[TPG_MAX_PLANES][8];
1601 	unsigned pat;
1602 	unsigned p;
1603 	unsigned x;
1604 
1605 	switch (tpg->pattern) {
1606 	case TPG_PAT_GREEN:
1607 		contrast = TPG_COLOR_100_RED;
1608 		break;
1609 	case TPG_PAT_CSC_COLORBAR:
1610 		contrast = TPG_COLOR_CSC_GREEN;
1611 		break;
1612 	default:
1613 		contrast = TPG_COLOR_100_GREEN;
1614 		break;
1615 	}
1616 
1617 	for (pat = 0; pat < tpg_get_pat_lines(tpg); pat++) {
1618 		/* Coarse scaling with Bresenham */
1619 		unsigned int_part = tpg->src_width / tpg->scaled_width;
1620 		unsigned fract_part = tpg->src_width % tpg->scaled_width;
1621 		unsigned src_x = 0;
1622 		unsigned error = 0;
1623 
1624 		for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1625 			unsigned real_x = src_x;
1626 			enum tpg_color color1, color2;
1627 
1628 			real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1629 			color1 = tpg_get_color(tpg, pat, real_x);
1630 
1631 			src_x += int_part;
1632 			error += fract_part;
1633 			if (error >= tpg->scaled_width) {
1634 				error -= tpg->scaled_width;
1635 				src_x++;
1636 			}
1637 
1638 			real_x = src_x;
1639 			real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
1640 			color2 = tpg_get_color(tpg, pat, real_x);
1641 
1642 			src_x += int_part;
1643 			error += fract_part;
1644 			if (error >= tpg->scaled_width) {
1645 				error -= tpg->scaled_width;
1646 				src_x++;
1647 			}
1648 
1649 			gen_twopix(tpg, pix, tpg->hflip ? color2 : color1, 0);
1650 			gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1651 			for (p = 0; p < tpg->planes; p++) {
1652 				unsigned twopixsize = tpg->twopixelsize[p];
1653 				unsigned hdiv = tpg->hdownsampling[p];
1654 				u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
1655 
1656 				memcpy(pos, pix[p], twopixsize / hdiv);
1657 			}
1658 		}
1659 	}
1660 
1661 	if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1662 		unsigned pat_lines = tpg_get_pat_lines(tpg);
1663 
1664 		for (pat = 0; pat < pat_lines; pat++) {
1665 			unsigned next_pat = (pat + 1) % pat_lines;
1666 
1667 			for (p = 1; p < tpg->planes; p++) {
1668 				unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
1669 				u8 *pos1 = tpg->lines[pat][p];
1670 				u8 *pos2 = tpg->lines[next_pat][p];
1671 				u8 *dest = tpg->downsampled_lines[pat][p];
1672 
1673 				for (x = 0; x < w; x++, pos1++, pos2++, dest++)
1674 					*dest = ((u16)*pos1 + (u16)*pos2) / 2;
1675 			}
1676 		}
1677 	}
1678 
1679 	gen_twopix(tpg, pix, contrast, 0);
1680 	gen_twopix(tpg, pix, contrast, 1);
1681 	for (p = 0; p < tpg->planes; p++) {
1682 		unsigned twopixsize = tpg->twopixelsize[p];
1683 		u8 *pos = tpg->contrast_line[p];
1684 
1685 		for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1686 			memcpy(pos, pix[p], twopixsize);
1687 	}
1688 
1689 	gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
1690 	gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
1691 	for (p = 0; p < tpg->planes; p++) {
1692 		unsigned twopixsize = tpg->twopixelsize[p];
1693 		u8 *pos = tpg->black_line[p];
1694 
1695 		for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1696 			memcpy(pos, pix[p], twopixsize);
1697 	}
1698 
1699 	for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1700 		gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
1701 		gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
1702 		for (p = 0; p < tpg->planes; p++) {
1703 			unsigned twopixsize = tpg->twopixelsize[p];
1704 			u8 *pos = tpg->random_line[p] + x * twopixsize / 2;
1705 
1706 			memcpy(pos, pix[p], twopixsize);
1707 		}
1708 	}
1709 
1710 	gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
1711 	gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
1712 	gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
1713 	gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 1);
1714 }
1715 
1716 /* need this to do rgb24 rendering */
1717 typedef struct { u16 __; u8 _; } __packed x24;
1718 
1719 #define PRINTSTR(PIXTYPE) do {	\
1720 	unsigned vdiv = tpg->vdownsampling[p]; \
1721 	unsigned hdiv = tpg->hdownsampling[p]; \
1722 	int line;	\
1723 	PIXTYPE fg;	\
1724 	PIXTYPE bg;	\
1725 	memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE));	\
1726 	memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE));	\
1727 	\
1728 	for (line = first; line < 16; line += vdiv * step) {	\
1729 		int l = tpg->vflip ? 15 - line : line; \
1730 		PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \
1731 			       ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
1732 			       (x / hdiv) * sizeof(PIXTYPE));	\
1733 		unsigned s;	\
1734 	\
1735 		for (s = 0; s < len; s++) {	\
1736 			u8 chr = font8x16[text[s] * 16 + line];	\
1737 	\
1738 			if (hdiv == 2 && tpg->hflip) { \
1739 				pos[3] = (chr & (0x01 << 6) ? fg : bg);	\
1740 				pos[2] = (chr & (0x01 << 4) ? fg : bg);	\
1741 				pos[1] = (chr & (0x01 << 2) ? fg : bg);	\
1742 				pos[0] = (chr & (0x01 << 0) ? fg : bg);	\
1743 			} else if (hdiv == 2) { \
1744 				pos[0] = (chr & (0x01 << 7) ? fg : bg);	\
1745 				pos[1] = (chr & (0x01 << 5) ? fg : bg);	\
1746 				pos[2] = (chr & (0x01 << 3) ? fg : bg);	\
1747 				pos[3] = (chr & (0x01 << 1) ? fg : bg);	\
1748 			} else if (tpg->hflip) { \
1749 				pos[7] = (chr & (0x01 << 7) ? fg : bg);	\
1750 				pos[6] = (chr & (0x01 << 6) ? fg : bg);	\
1751 				pos[5] = (chr & (0x01 << 5) ? fg : bg);	\
1752 				pos[4] = (chr & (0x01 << 4) ? fg : bg);	\
1753 				pos[3] = (chr & (0x01 << 3) ? fg : bg);	\
1754 				pos[2] = (chr & (0x01 << 2) ? fg : bg);	\
1755 				pos[1] = (chr & (0x01 << 1) ? fg : bg);	\
1756 				pos[0] = (chr & (0x01 << 0) ? fg : bg);	\
1757 			} else { \
1758 				pos[0] = (chr & (0x01 << 7) ? fg : bg);	\
1759 				pos[1] = (chr & (0x01 << 6) ? fg : bg);	\
1760 				pos[2] = (chr & (0x01 << 5) ? fg : bg);	\
1761 				pos[3] = (chr & (0x01 << 4) ? fg : bg);	\
1762 				pos[4] = (chr & (0x01 << 3) ? fg : bg);	\
1763 				pos[5] = (chr & (0x01 << 2) ? fg : bg);	\
1764 				pos[6] = (chr & (0x01 << 1) ? fg : bg);	\
1765 				pos[7] = (chr & (0x01 << 0) ? fg : bg);	\
1766 			} \
1767 	\
1768 			pos += (tpg->hflip ? -8 : 8) / hdiv;	\
1769 		}	\
1770 	}	\
1771 } while (0)
1772 
1773 static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1774 			unsigned p, unsigned first, unsigned div, unsigned step,
1775 			int y, int x, char *text, unsigned len)
1776 {
1777 	PRINTSTR(u8);
1778 }
1779 
1780 static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1781 			unsigned p, unsigned first, unsigned div, unsigned step,
1782 			int y, int x, char *text, unsigned len)
1783 {
1784 	PRINTSTR(u16);
1785 }
1786 
1787 static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1788 			unsigned p, unsigned first, unsigned div, unsigned step,
1789 			int y, int x, char *text, unsigned len)
1790 {
1791 	PRINTSTR(x24);
1792 }
1793 
1794 static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1795 			unsigned p, unsigned first, unsigned div, unsigned step,
1796 			int y, int x, char *text, unsigned len)
1797 {
1798 	PRINTSTR(u32);
1799 }
1800 
1801 void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1802 		  int y, int x, char *text)
1803 {
1804 	unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1805 	unsigned div = step;
1806 	unsigned first = 0;
1807 	unsigned len = strlen(text);
1808 	unsigned p;
1809 
1810 	if (font8x16 == NULL || basep == NULL)
1811 		return;
1812 
1813 	/* Checks if it is possible to show string */
1814 	if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
1815 		return;
1816 
1817 	if (len > (tpg->compose.width - x) / 8)
1818 		len = (tpg->compose.width - x) / 8;
1819 	if (tpg->vflip)
1820 		y = tpg->compose.height - y - 16;
1821 	if (tpg->hflip)
1822 		x = tpg->compose.width - x - 8;
1823 	y += tpg->compose.top;
1824 	x += tpg->compose.left;
1825 	if (tpg->field == V4L2_FIELD_BOTTOM)
1826 		first = 1;
1827 	else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
1828 		div = 2;
1829 
1830 	for (p = 0; p < tpg->planes; p++) {
1831 		/* Print text */
1832 		switch (tpg->twopixelsize[p]) {
1833 		case 2:
1834 			tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
1835 					text, len);
1836 			break;
1837 		case 4:
1838 			tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
1839 					text, len);
1840 			break;
1841 		case 6:
1842 			tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
1843 					text, len);
1844 			break;
1845 		case 8:
1846 			tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
1847 					text, len);
1848 			break;
1849 		}
1850 	}
1851 }
1852 EXPORT_SYMBOL_GPL(tpg_gen_text);
1853 
1854 void tpg_update_mv_step(struct tpg_data *tpg)
1855 {
1856 	int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
1857 
1858 	if (tpg->hflip)
1859 		factor = -factor;
1860 	switch (tpg->mv_hor_mode) {
1861 	case TPG_MOVE_NEG_FAST:
1862 	case TPG_MOVE_POS_FAST:
1863 		tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
1864 		break;
1865 	case TPG_MOVE_NEG:
1866 	case TPG_MOVE_POS:
1867 		tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
1868 		break;
1869 	case TPG_MOVE_NEG_SLOW:
1870 	case TPG_MOVE_POS_SLOW:
1871 		tpg->mv_hor_step = 2;
1872 		break;
1873 	case TPG_MOVE_NONE:
1874 		tpg->mv_hor_step = 0;
1875 		break;
1876 	}
1877 	if (factor < 0)
1878 		tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
1879 
1880 	factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
1881 	switch (tpg->mv_vert_mode) {
1882 	case TPG_MOVE_NEG_FAST:
1883 	case TPG_MOVE_POS_FAST:
1884 		tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
1885 		break;
1886 	case TPG_MOVE_NEG:
1887 	case TPG_MOVE_POS:
1888 		tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
1889 		break;
1890 	case TPG_MOVE_NEG_SLOW:
1891 	case TPG_MOVE_POS_SLOW:
1892 		tpg->mv_vert_step = 1;
1893 		break;
1894 	case TPG_MOVE_NONE:
1895 		tpg->mv_vert_step = 0;
1896 		break;
1897 	}
1898 	if (factor < 0)
1899 		tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
1900 }
1901 EXPORT_SYMBOL_GPL(tpg_update_mv_step);
1902 
1903 /* Map the line number relative to the crop rectangle to a frame line number */
1904 static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
1905 				    unsigned field)
1906 {
1907 	switch (field) {
1908 	case V4L2_FIELD_TOP:
1909 		return tpg->crop.top + src_y * 2;
1910 	case V4L2_FIELD_BOTTOM:
1911 		return tpg->crop.top + src_y * 2 + 1;
1912 	default:
1913 		return src_y + tpg->crop.top;
1914 	}
1915 }
1916 
1917 /*
1918  * Map the line number relative to the compose rectangle to a destination
1919  * buffer line number.
1920  */
1921 static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
1922 				    unsigned field)
1923 {
1924 	y += tpg->compose.top;
1925 	switch (field) {
1926 	case V4L2_FIELD_SEQ_TB:
1927 		if (y & 1)
1928 			return tpg->buf_height / 2 + y / 2;
1929 		return y / 2;
1930 	case V4L2_FIELD_SEQ_BT:
1931 		if (y & 1)
1932 			return y / 2;
1933 		return tpg->buf_height / 2 + y / 2;
1934 	default:
1935 		return y;
1936 	}
1937 }
1938 
1939 static void tpg_recalc(struct tpg_data *tpg)
1940 {
1941 	if (tpg->recalc_colors) {
1942 		tpg->recalc_colors = false;
1943 		tpg->recalc_lines = true;
1944 		tpg->real_xfer_func = tpg->xfer_func;
1945 		tpg->real_ycbcr_enc = tpg->ycbcr_enc;
1946 		tpg->real_hsv_enc = tpg->hsv_enc;
1947 		tpg->real_quantization = tpg->quantization;
1948 
1949 		if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
1950 			tpg->real_xfer_func =
1951 				V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
1952 
1953 		if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
1954 			tpg->real_ycbcr_enc =
1955 				V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
1956 
1957 		if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
1958 			tpg->real_quantization =
1959 				V4L2_MAP_QUANTIZATION_DEFAULT(
1960 					tpg->color_enc != TGP_COLOR_ENC_YCBCR,
1961 					tpg->colorspace, tpg->real_ycbcr_enc);
1962 
1963 		tpg_precalculate_colors(tpg);
1964 	}
1965 	if (tpg->recalc_square_border) {
1966 		tpg->recalc_square_border = false;
1967 		tpg_calculate_square_border(tpg);
1968 	}
1969 	if (tpg->recalc_lines) {
1970 		tpg->recalc_lines = false;
1971 		tpg_precalculate_line(tpg);
1972 	}
1973 }
1974 
1975 void tpg_calc_text_basep(struct tpg_data *tpg,
1976 		u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
1977 {
1978 	unsigned stride = tpg->bytesperline[p];
1979 	unsigned h = tpg->buf_height;
1980 
1981 	tpg_recalc(tpg);
1982 
1983 	basep[p][0] = vbuf;
1984 	basep[p][1] = vbuf;
1985 	h /= tpg->vdownsampling[p];
1986 	if (tpg->field == V4L2_FIELD_SEQ_TB)
1987 		basep[p][1] += h * stride / 2;
1988 	else if (tpg->field == V4L2_FIELD_SEQ_BT)
1989 		basep[p][0] += h * stride / 2;
1990 	if (p == 0 && tpg->interleaved)
1991 		tpg_calc_text_basep(tpg, basep, 1, vbuf);
1992 }
1993 EXPORT_SYMBOL_GPL(tpg_calc_text_basep);
1994 
1995 static int tpg_pattern_avg(const struct tpg_data *tpg,
1996 			   unsigned pat1, unsigned pat2)
1997 {
1998 	unsigned pat_lines = tpg_get_pat_lines(tpg);
1999 
2000 	if (pat1 == (pat2 + 1) % pat_lines)
2001 		return pat2;
2002 	if (pat2 == (pat1 + 1) % pat_lines)
2003 		return pat1;
2004 	return -1;
2005 }
2006 
2007 static const char *tpg_color_enc_str(enum tgp_color_enc
2008 						 color_enc)
2009 {
2010 	switch (color_enc) {
2011 	case TGP_COLOR_ENC_HSV:
2012 		return "HSV";
2013 	case TGP_COLOR_ENC_YCBCR:
2014 		return "Y'CbCr";
2015 	case TGP_COLOR_ENC_LUMA:
2016 		return "Luma";
2017 	case TGP_COLOR_ENC_RGB:
2018 	default:
2019 		return "R'G'B";
2020 
2021 	}
2022 }
2023 
2024 void tpg_log_status(struct tpg_data *tpg)
2025 {
2026 	pr_info("tpg source WxH: %ux%u (%s)\n",
2027 		tpg->src_width, tpg->src_height,
2028 		tpg_color_enc_str(tpg->color_enc));
2029 	pr_info("tpg field: %u\n", tpg->field);
2030 	pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
2031 			tpg->crop.left, tpg->crop.top);
2032 	pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
2033 			tpg->compose.left, tpg->compose.top);
2034 	pr_info("tpg colorspace: %d\n", tpg->colorspace);
2035 	pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
2036 	pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
2037 	pr_info("tpg HSV encoding: %d/%d\n", tpg->hsv_enc, tpg->real_hsv_enc);
2038 	pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
2039 	pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
2040 }
2041 EXPORT_SYMBOL_GPL(tpg_log_status);
2042 
2043 /*
2044  * This struct contains common parameters used by both the drawing of the
2045  * test pattern and the drawing of the extras (borders, square, etc.)
2046  */
2047 struct tpg_draw_params {
2048 	/* common data */
2049 	bool is_tv;
2050 	bool is_60hz;
2051 	unsigned twopixsize;
2052 	unsigned img_width;
2053 	unsigned stride;
2054 	unsigned hmax;
2055 	unsigned frame_line;
2056 	unsigned frame_line_next;
2057 
2058 	/* test pattern */
2059 	unsigned mv_hor_old;
2060 	unsigned mv_hor_new;
2061 	unsigned mv_vert_old;
2062 	unsigned mv_vert_new;
2063 
2064 	/* extras */
2065 	unsigned wss_width;
2066 	unsigned wss_random_offset;
2067 	unsigned sav_eav_f;
2068 	unsigned left_pillar_width;
2069 	unsigned right_pillar_start;
2070 };
2071 
2072 static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
2073 				    struct tpg_draw_params *params)
2074 {
2075 	params->mv_hor_old =
2076 		tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
2077 	params->mv_hor_new =
2078 		tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
2079 			       tpg->src_width);
2080 	params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
2081 	params->mv_vert_new =
2082 		(tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
2083 }
2084 
2085 static void tpg_fill_params_extras(const struct tpg_data *tpg,
2086 				   unsigned p,
2087 				   struct tpg_draw_params *params)
2088 {
2089 	unsigned left_pillar_width = 0;
2090 	unsigned right_pillar_start = params->img_width;
2091 
2092 	params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
2093 		tpg->src_width / 2 - tpg->crop.left : 0;
2094 	if (params->wss_width > tpg->crop.width)
2095 		params->wss_width = tpg->crop.width;
2096 	params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
2097 	params->wss_random_offset =
2098 		params->twopixsize * prandom_u32_max(tpg->src_width / 2);
2099 
2100 	if (tpg->crop.left < tpg->border.left) {
2101 		left_pillar_width = tpg->border.left - tpg->crop.left;
2102 		if (left_pillar_width > tpg->crop.width)
2103 			left_pillar_width = tpg->crop.width;
2104 		left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
2105 	}
2106 	params->left_pillar_width = left_pillar_width;
2107 
2108 	if (tpg->crop.left + tpg->crop.width >
2109 	    tpg->border.left + tpg->border.width) {
2110 		right_pillar_start =
2111 			tpg->border.left + tpg->border.width - tpg->crop.left;
2112 		right_pillar_start =
2113 			tpg_hscale_div(tpg, p, right_pillar_start);
2114 		if (right_pillar_start > params->img_width)
2115 			right_pillar_start = params->img_width;
2116 	}
2117 	params->right_pillar_start = right_pillar_start;
2118 
2119 	params->sav_eav_f = tpg->field ==
2120 			(params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
2121 }
2122 
2123 static void tpg_fill_plane_extras(const struct tpg_data *tpg,
2124 				  const struct tpg_draw_params *params,
2125 				  unsigned p, unsigned h, u8 *vbuf)
2126 {
2127 	unsigned twopixsize = params->twopixsize;
2128 	unsigned img_width = params->img_width;
2129 	unsigned frame_line = params->frame_line;
2130 	const struct v4l2_rect *sq = &tpg->square;
2131 	const struct v4l2_rect *b = &tpg->border;
2132 	const struct v4l2_rect *c = &tpg->crop;
2133 
2134 	if (params->is_tv && !params->is_60hz &&
2135 	    frame_line == 0 && params->wss_width) {
2136 		/*
2137 		 * Replace the first half of the top line of a 50 Hz frame
2138 		 * with random data to simulate a WSS signal.
2139 		 */
2140 		u8 *wss = tpg->random_line[p] + params->wss_random_offset;
2141 
2142 		memcpy(vbuf, wss, params->wss_width);
2143 	}
2144 
2145 	if (tpg->show_border && frame_line >= b->top &&
2146 	    frame_line < b->top + b->height) {
2147 		unsigned bottom = b->top + b->height - 1;
2148 		unsigned left = params->left_pillar_width;
2149 		unsigned right = params->right_pillar_start;
2150 
2151 		if (frame_line == b->top || frame_line == b->top + 1 ||
2152 		    frame_line == bottom || frame_line == bottom - 1) {
2153 			memcpy(vbuf + left, tpg->contrast_line[p],
2154 					right - left);
2155 		} else {
2156 			if (b->left >= c->left &&
2157 			    b->left < c->left + c->width)
2158 				memcpy(vbuf + left,
2159 					tpg->contrast_line[p], twopixsize);
2160 			if (b->left + b->width > c->left &&
2161 			    b->left + b->width <= c->left + c->width)
2162 				memcpy(vbuf + right - twopixsize,
2163 					tpg->contrast_line[p], twopixsize);
2164 		}
2165 	}
2166 	if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
2167 	    frame_line < b->top + b->height) {
2168 		memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
2169 		memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
2170 		       img_width - params->right_pillar_start);
2171 	}
2172 	if (tpg->show_square && frame_line >= sq->top &&
2173 	    frame_line < sq->top + sq->height &&
2174 	    sq->left < c->left + c->width &&
2175 	    sq->left + sq->width >= c->left) {
2176 		unsigned left = sq->left;
2177 		unsigned width = sq->width;
2178 
2179 		if (c->left > left) {
2180 			width -= c->left - left;
2181 			left = c->left;
2182 		}
2183 		if (c->left + c->width < left + width)
2184 			width -= left + width - c->left - c->width;
2185 		left -= c->left;
2186 		left = tpg_hscale_div(tpg, p, left);
2187 		width = tpg_hscale_div(tpg, p, width);
2188 		memcpy(vbuf + left, tpg->contrast_line[p], width);
2189 	}
2190 	if (tpg->insert_sav) {
2191 		unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
2192 		u8 *p = vbuf + offset;
2193 		unsigned vact = 0, hact = 0;
2194 
2195 		p[0] = 0xff;
2196 		p[1] = 0;
2197 		p[2] = 0;
2198 		p[3] = 0x80 | (params->sav_eav_f << 6) |
2199 			(vact << 5) | (hact << 4) |
2200 			((hact ^ vact) << 3) |
2201 			((hact ^ params->sav_eav_f) << 2) |
2202 			((params->sav_eav_f ^ vact) << 1) |
2203 			(hact ^ vact ^ params->sav_eav_f);
2204 	}
2205 	if (tpg->insert_eav) {
2206 		unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
2207 		u8 *p = vbuf + offset;
2208 		unsigned vact = 0, hact = 1;
2209 
2210 		p[0] = 0xff;
2211 		p[1] = 0;
2212 		p[2] = 0;
2213 		p[3] = 0x80 | (params->sav_eav_f << 6) |
2214 			(vact << 5) | (hact << 4) |
2215 			((hact ^ vact) << 3) |
2216 			((hact ^ params->sav_eav_f) << 2) |
2217 			((params->sav_eav_f ^ vact) << 1) |
2218 			(hact ^ vact ^ params->sav_eav_f);
2219 	}
2220 }
2221 
2222 static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
2223 				   const struct tpg_draw_params *params,
2224 				   unsigned p, unsigned h, u8 *vbuf)
2225 {
2226 	unsigned twopixsize = params->twopixsize;
2227 	unsigned img_width = params->img_width;
2228 	unsigned mv_hor_old = params->mv_hor_old;
2229 	unsigned mv_hor_new = params->mv_hor_new;
2230 	unsigned mv_vert_old = params->mv_vert_old;
2231 	unsigned mv_vert_new = params->mv_vert_new;
2232 	unsigned frame_line = params->frame_line;
2233 	unsigned frame_line_next = params->frame_line_next;
2234 	unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
2235 	bool even;
2236 	bool fill_blank = false;
2237 	unsigned pat_line_old;
2238 	unsigned pat_line_new;
2239 	u8 *linestart_older;
2240 	u8 *linestart_newer;
2241 	u8 *linestart_top;
2242 	u8 *linestart_bottom;
2243 
2244 	even = !(frame_line & 1);
2245 
2246 	if (h >= params->hmax) {
2247 		if (params->hmax == tpg->compose.height)
2248 			return;
2249 		if (!tpg->perc_fill_blank)
2250 			return;
2251 		fill_blank = true;
2252 	}
2253 
2254 	if (tpg->vflip) {
2255 		frame_line = tpg->src_height - frame_line - 1;
2256 		frame_line_next = tpg->src_height - frame_line_next - 1;
2257 	}
2258 
2259 	if (fill_blank) {
2260 		linestart_older = tpg->contrast_line[p];
2261 		linestart_newer = tpg->contrast_line[p];
2262 	} else if (tpg->qual != TPG_QUAL_NOISE &&
2263 		   (frame_line < tpg->border.top ||
2264 		    frame_line >= tpg->border.top + tpg->border.height)) {
2265 		linestart_older = tpg->black_line[p];
2266 		linestart_newer = tpg->black_line[p];
2267 	} else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
2268 		linestart_older = tpg->random_line[p] +
2269 				  twopixsize * prandom_u32_max(tpg->src_width / 2);
2270 		linestart_newer = tpg->random_line[p] +
2271 				  twopixsize * prandom_u32_max(tpg->src_width / 2);
2272 	} else {
2273 		unsigned frame_line_old =
2274 			(frame_line + mv_vert_old) % tpg->src_height;
2275 		unsigned frame_line_new =
2276 			(frame_line + mv_vert_new) % tpg->src_height;
2277 		unsigned pat_line_next_old;
2278 		unsigned pat_line_next_new;
2279 
2280 		pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
2281 		pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
2282 		linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
2283 		linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
2284 
2285 		if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
2286 			int avg_pat;
2287 
2288 			/*
2289 			 * Now decide whether we need to use downsampled_lines[].
2290 			 * That's necessary if the two lines use different patterns.
2291 			 */
2292 			pat_line_next_old = tpg_get_pat_line(tpg,
2293 					(frame_line_next + mv_vert_old) % tpg->src_height);
2294 			pat_line_next_new = tpg_get_pat_line(tpg,
2295 					(frame_line_next + mv_vert_new) % tpg->src_height);
2296 
2297 			switch (tpg->field) {
2298 			case V4L2_FIELD_INTERLACED:
2299 			case V4L2_FIELD_INTERLACED_BT:
2300 			case V4L2_FIELD_INTERLACED_TB:
2301 				avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
2302 				if (avg_pat < 0)
2303 					break;
2304 				linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
2305 				linestart_newer = linestart_older;
2306 				break;
2307 			case V4L2_FIELD_NONE:
2308 			case V4L2_FIELD_TOP:
2309 			case V4L2_FIELD_BOTTOM:
2310 			case V4L2_FIELD_SEQ_BT:
2311 			case V4L2_FIELD_SEQ_TB:
2312 				avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
2313 				if (avg_pat >= 0)
2314 					linestart_older = tpg->downsampled_lines[avg_pat][p] +
2315 						mv_hor_old;
2316 				avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
2317 				if (avg_pat >= 0)
2318 					linestart_newer = tpg->downsampled_lines[avg_pat][p] +
2319 						mv_hor_new;
2320 				break;
2321 			}
2322 		}
2323 		linestart_older += line_offset;
2324 		linestart_newer += line_offset;
2325 	}
2326 	if (tpg->field_alternate) {
2327 		linestart_top = linestart_bottom = linestart_older;
2328 	} else if (params->is_60hz) {
2329 		linestart_top = linestart_newer;
2330 		linestart_bottom = linestart_older;
2331 	} else {
2332 		linestart_top = linestart_older;
2333 		linestart_bottom = linestart_newer;
2334 	}
2335 
2336 	switch (tpg->field) {
2337 	case V4L2_FIELD_INTERLACED:
2338 	case V4L2_FIELD_INTERLACED_TB:
2339 	case V4L2_FIELD_SEQ_TB:
2340 	case V4L2_FIELD_SEQ_BT:
2341 		if (even)
2342 			memcpy(vbuf, linestart_top, img_width);
2343 		else
2344 			memcpy(vbuf, linestart_bottom, img_width);
2345 		break;
2346 	case V4L2_FIELD_INTERLACED_BT:
2347 		if (even)
2348 			memcpy(vbuf, linestart_bottom, img_width);
2349 		else
2350 			memcpy(vbuf, linestart_top, img_width);
2351 		break;
2352 	case V4L2_FIELD_TOP:
2353 		memcpy(vbuf, linestart_top, img_width);
2354 		break;
2355 	case V4L2_FIELD_BOTTOM:
2356 		memcpy(vbuf, linestart_bottom, img_width);
2357 		break;
2358 	case V4L2_FIELD_NONE:
2359 	default:
2360 		memcpy(vbuf, linestart_older, img_width);
2361 		break;
2362 	}
2363 }
2364 
2365 void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
2366 			   unsigned p, u8 *vbuf)
2367 {
2368 	struct tpg_draw_params params;
2369 	unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2370 
2371 	/* Coarse scaling with Bresenham */
2372 	unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2373 	unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2374 	unsigned src_y = 0;
2375 	unsigned error = 0;
2376 	unsigned h;
2377 
2378 	tpg_recalc(tpg);
2379 
2380 	params.is_tv = std;
2381 	params.is_60hz = std & V4L2_STD_525_60;
2382 	params.twopixsize = tpg->twopixelsize[p];
2383 	params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2384 	params.stride = tpg->bytesperline[p];
2385 	params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2386 
2387 	tpg_fill_params_pattern(tpg, p, &params);
2388 	tpg_fill_params_extras(tpg, p, &params);
2389 
2390 	vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
2391 
2392 	for (h = 0; h < tpg->compose.height; h++) {
2393 		unsigned buf_line;
2394 
2395 		params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2396 		params.frame_line_next = params.frame_line;
2397 		buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
2398 		src_y += int_part;
2399 		error += fract_part;
2400 		if (error >= tpg->compose.height) {
2401 			error -= tpg->compose.height;
2402 			src_y++;
2403 		}
2404 
2405 		/*
2406 		 * For line-interleaved formats determine the 'plane'
2407 		 * based on the buffer line.
2408 		 */
2409 		if (tpg_g_interleaved(tpg))
2410 			p = tpg_g_interleaved_plane(tpg, buf_line);
2411 
2412 		if (tpg->vdownsampling[p] > 1) {
2413 			/*
2414 			 * When doing vertical downsampling the field setting
2415 			 * matters: for SEQ_BT/TB we downsample each field
2416 			 * separately (i.e. lines 0+2 are combined, as are
2417 			 * lines 1+3), for the other field settings we combine
2418 			 * odd and even lines. Doing that for SEQ_BT/TB would
2419 			 * be really weird.
2420 			 */
2421 			if (tpg->field == V4L2_FIELD_SEQ_BT ||
2422 			    tpg->field == V4L2_FIELD_SEQ_TB) {
2423 				unsigned next_src_y = src_y;
2424 
2425 				if ((h & 3) >= 2)
2426 					continue;
2427 				next_src_y += int_part;
2428 				if (error + fract_part >= tpg->compose.height)
2429 					next_src_y++;
2430 				params.frame_line_next =
2431 					tpg_calc_frameline(tpg, next_src_y, tpg->field);
2432 			} else {
2433 				if (h & 1)
2434 					continue;
2435 				params.frame_line_next =
2436 					tpg_calc_frameline(tpg, src_y, tpg->field);
2437 			}
2438 
2439 			buf_line /= tpg->vdownsampling[p];
2440 		}
2441 		tpg_fill_plane_pattern(tpg, &params, p, h,
2442 				vbuf + buf_line * params.stride);
2443 		tpg_fill_plane_extras(tpg, &params, p, h,
2444 				vbuf + buf_line * params.stride);
2445 	}
2446 }
2447 EXPORT_SYMBOL_GPL(tpg_fill_plane_buffer);
2448 
2449 void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
2450 {
2451 	unsigned offset = 0;
2452 	unsigned i;
2453 
2454 	if (tpg->buffers > 1) {
2455 		tpg_fill_plane_buffer(tpg, std, p, vbuf);
2456 		return;
2457 	}
2458 
2459 	for (i = 0; i < tpg_g_planes(tpg); i++) {
2460 		tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
2461 		offset += tpg_calc_plane_size(tpg, i);
2462 	}
2463 }
2464 EXPORT_SYMBOL_GPL(tpg_fillbuffer);
2465 
2466 MODULE_DESCRIPTION("V4L2 Test Pattern Generator");
2467 MODULE_AUTHOR("Hans Verkuil");
2468 MODULE_LICENSE("GPL");
2469