1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * v4l2-tpg-core.c - Test Pattern Generator
4  *
5  * Note: gen_twopix and tpg_gen_text are based on code from vivi.c. See the
6  * vivi.c source for the copyright information of those functions.
7  *
8  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
9  */
10 
11 #include <linux/module.h>
12 #include <media/tpg/v4l2-tpg.h>
13 
14 /* Must remain in sync with enum tpg_pattern */
15 const char * const tpg_pattern_strings[] = {
16 	"75% Colorbar",
17 	"100% Colorbar",
18 	"CSC Colorbar",
19 	"Horizontal 100% Colorbar",
20 	"100% Color Squares",
21 	"100% Black",
22 	"100% White",
23 	"100% Red",
24 	"100% Green",
25 	"100% Blue",
26 	"16x16 Checkers",
27 	"2x2 Checkers",
28 	"1x1 Checkers",
29 	"2x2 Red/Green Checkers",
30 	"1x1 Red/Green Checkers",
31 	"Alternating Hor Lines",
32 	"Alternating Vert Lines",
33 	"One Pixel Wide Cross",
34 	"Two Pixels Wide Cross",
35 	"Ten Pixels Wide Cross",
36 	"Gray Ramp",
37 	"Noise",
38 	NULL
39 };
40 EXPORT_SYMBOL_GPL(tpg_pattern_strings);
41 
42 /* Must remain in sync with enum tpg_aspect */
43 const char * const tpg_aspect_strings[] = {
44 	"Source Width x Height",
45 	"4x3",
46 	"14x9",
47 	"16x9",
48 	"16x9 Anamorphic",
49 	NULL
50 };
51 EXPORT_SYMBOL_GPL(tpg_aspect_strings);
52 
53 /*
54  * Sine table: sin[0] = 127 * sin(-180 degrees)
55  *             sin[128] = 127 * sin(0 degrees)
56  *             sin[256] = 127 * sin(180 degrees)
57  */
58 static const s8 sin[257] = {
59 	   0,   -4,   -7,  -11,  -13,  -18,  -20,  -22,  -26,  -29,  -33,  -35,  -37,  -41,  -43,  -48,
60 	 -50,  -52,  -56,  -58,  -62,  -63,  -65,  -69,  -71,  -75,  -76,  -78,  -82,  -83,  -87,  -88,
61 	 -90,  -93,  -94,  -97,  -99, -101, -103, -104, -107, -108, -110, -111, -112, -114, -115, -117,
62 	-118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -127, -127, -127, -127,
63 	-127, -127, -127, -127, -126, -126, -125, -125, -124, -124, -123, -122, -121, -120, -119, -118,
64 	-117, -116, -114, -113, -111, -110, -109, -107, -105, -103, -101, -100,  -97,  -96,  -93,  -91,
65 	 -90,  -87,  -85,  -82,  -80,  -76,  -75,  -73,  -69,  -67,  -63,  -62,  -60,  -56,  -54,  -50,
66 	 -48,  -46,  -41,  -39,  -35,  -33,  -31,  -26,  -24,  -20,  -18,  -15,  -11,   -9,   -4,   -2,
67 	   0,    2,    4,    9,   11,   15,   18,   20,   24,   26,   31,   33,   35,   39,   41,   46,
68 	  48,   50,   54,   56,   60,   62,   64,   67,   69,   73,   75,   76,   80,   82,   85,   87,
69 	  90,   91,   93,   96,   97,  100,  101,  103,  105,  107,  109,  110,  111,  113,  114,  116,
70 	 117,  118,  119,  120,  121,  122,  123,  124,  124,  125,  125,  126,  126,  127,  127,  127,
71 	 127,  127,  127,  127,  127,  126,  126,  125,  125,  124,  123,  123,  122,  121,  120,  119,
72 	 118,  117,  115,  114,  112,  111,  110,  108,  107,  104,  103,  101,   99,   97,   94,   93,
73 	  90,   88,   87,   83,   82,   78,   76,   75,   71,   69,   65,   64,   62,   58,   56,   52,
74 	  50,   48,   43,   41,   37,   35,   33,   29,   26,   22,   20,   18,   13,   11,    7,    4,
75 	   0,
76 };
77 
78 #define cos(idx) sin[((idx) + 64) % sizeof(sin)]
79 
80 /* Global font descriptor */
81 static const u8 *font8x16;
82 
83 void tpg_set_font(const u8 *f)
84 {
85 	font8x16 = f;
86 }
87 EXPORT_SYMBOL_GPL(tpg_set_font);
88 
89 void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
90 {
91 	memset(tpg, 0, sizeof(*tpg));
92 	tpg->scaled_width = tpg->src_width = w;
93 	tpg->src_height = tpg->buf_height = h;
94 	tpg->crop.width = tpg->compose.width = w;
95 	tpg->crop.height = tpg->compose.height = h;
96 	tpg->recalc_colors = true;
97 	tpg->recalc_square_border = true;
98 	tpg->brightness = 128;
99 	tpg->contrast = 128;
100 	tpg->saturation = 128;
101 	tpg->hue = 0;
102 	tpg->mv_hor_mode = TPG_MOVE_NONE;
103 	tpg->mv_vert_mode = TPG_MOVE_NONE;
104 	tpg->field = V4L2_FIELD_NONE;
105 	tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
106 	tpg->colorspace = V4L2_COLORSPACE_SRGB;
107 	tpg->perc_fill = 100;
108 	tpg->hsv_enc = V4L2_HSV_ENC_180;
109 }
110 EXPORT_SYMBOL_GPL(tpg_init);
111 
112 int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
113 {
114 	unsigned pat;
115 	unsigned plane;
116 
117 	tpg->max_line_width = max_w;
118 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
119 		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
120 			unsigned pixelsz = plane ? 2 : 4;
121 
122 			tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
123 			if (!tpg->lines[pat][plane])
124 				return -ENOMEM;
125 			if (plane == 0)
126 				continue;
127 			tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
128 			if (!tpg->downsampled_lines[pat][plane])
129 				return -ENOMEM;
130 		}
131 	}
132 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
133 		unsigned pixelsz = plane ? 2 : 4;
134 
135 		tpg->contrast_line[plane] = vzalloc(max_w * pixelsz);
136 		if (!tpg->contrast_line[plane])
137 			return -ENOMEM;
138 		tpg->black_line[plane] = vzalloc(max_w * pixelsz);
139 		if (!tpg->black_line[plane])
140 			return -ENOMEM;
141 		tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz);
142 		if (!tpg->random_line[plane])
143 			return -ENOMEM;
144 	}
145 	return 0;
146 }
147 EXPORT_SYMBOL_GPL(tpg_alloc);
148 
149 void tpg_free(struct tpg_data *tpg)
150 {
151 	unsigned pat;
152 	unsigned plane;
153 
154 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
155 		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
156 			vfree(tpg->lines[pat][plane]);
157 			tpg->lines[pat][plane] = NULL;
158 			if (plane == 0)
159 				continue;
160 			vfree(tpg->downsampled_lines[pat][plane]);
161 			tpg->downsampled_lines[pat][plane] = NULL;
162 		}
163 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
164 		vfree(tpg->contrast_line[plane]);
165 		vfree(tpg->black_line[plane]);
166 		vfree(tpg->random_line[plane]);
167 		tpg->contrast_line[plane] = NULL;
168 		tpg->black_line[plane] = NULL;
169 		tpg->random_line[plane] = NULL;
170 	}
171 }
172 EXPORT_SYMBOL_GPL(tpg_free);
173 
174 bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
175 {
176 	tpg->fourcc = fourcc;
177 	tpg->planes = 1;
178 	tpg->buffers = 1;
179 	tpg->recalc_colors = true;
180 	tpg->interleaved = false;
181 	tpg->vdownsampling[0] = 1;
182 	tpg->hdownsampling[0] = 1;
183 	tpg->hmask[0] = ~0;
184 	tpg->hmask[1] = ~0;
185 	tpg->hmask[2] = ~0;
186 
187 	switch (fourcc) {
188 	case V4L2_PIX_FMT_SBGGR8:
189 	case V4L2_PIX_FMT_SGBRG8:
190 	case V4L2_PIX_FMT_SGRBG8:
191 	case V4L2_PIX_FMT_SRGGB8:
192 	case V4L2_PIX_FMT_SBGGR10:
193 	case V4L2_PIX_FMT_SGBRG10:
194 	case V4L2_PIX_FMT_SGRBG10:
195 	case V4L2_PIX_FMT_SRGGB10:
196 	case V4L2_PIX_FMT_SBGGR12:
197 	case V4L2_PIX_FMT_SGBRG12:
198 	case V4L2_PIX_FMT_SGRBG12:
199 	case V4L2_PIX_FMT_SRGGB12:
200 		tpg->interleaved = true;
201 		tpg->vdownsampling[1] = 1;
202 		tpg->hdownsampling[1] = 1;
203 		tpg->planes = 2;
204 		/* fall through */
205 	case V4L2_PIX_FMT_RGB332:
206 	case V4L2_PIX_FMT_RGB565:
207 	case V4L2_PIX_FMT_RGB565X:
208 	case V4L2_PIX_FMT_RGB444:
209 	case V4L2_PIX_FMT_XRGB444:
210 	case V4L2_PIX_FMT_ARGB444:
211 	case V4L2_PIX_FMT_RGB555:
212 	case V4L2_PIX_FMT_XRGB555:
213 	case V4L2_PIX_FMT_ARGB555:
214 	case V4L2_PIX_FMT_RGB555X:
215 	case V4L2_PIX_FMT_XRGB555X:
216 	case V4L2_PIX_FMT_ARGB555X:
217 	case V4L2_PIX_FMT_BGR666:
218 	case V4L2_PIX_FMT_RGB24:
219 	case V4L2_PIX_FMT_BGR24:
220 	case V4L2_PIX_FMT_RGB32:
221 	case V4L2_PIX_FMT_BGR32:
222 	case V4L2_PIX_FMT_XRGB32:
223 	case V4L2_PIX_FMT_XBGR32:
224 	case V4L2_PIX_FMT_ARGB32:
225 	case V4L2_PIX_FMT_ABGR32:
226 		tpg->color_enc = TGP_COLOR_ENC_RGB;
227 		break;
228 	case V4L2_PIX_FMT_GREY:
229 	case V4L2_PIX_FMT_Y10:
230 	case V4L2_PIX_FMT_Y12:
231 	case V4L2_PIX_FMT_Y16:
232 	case V4L2_PIX_FMT_Y16_BE:
233 		tpg->color_enc = TGP_COLOR_ENC_LUMA;
234 		break;
235 	case V4L2_PIX_FMT_YUV444:
236 	case V4L2_PIX_FMT_YUV555:
237 	case V4L2_PIX_FMT_YUV565:
238 	case V4L2_PIX_FMT_YUV32:
239 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
240 		break;
241 	case V4L2_PIX_FMT_YUV420M:
242 	case V4L2_PIX_FMT_YVU420M:
243 		tpg->buffers = 3;
244 		/* fall through */
245 	case V4L2_PIX_FMT_YUV420:
246 	case V4L2_PIX_FMT_YVU420:
247 		tpg->vdownsampling[1] = 2;
248 		tpg->vdownsampling[2] = 2;
249 		tpg->hdownsampling[1] = 2;
250 		tpg->hdownsampling[2] = 2;
251 		tpg->planes = 3;
252 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
253 		break;
254 	case V4L2_PIX_FMT_YUV422M:
255 	case V4L2_PIX_FMT_YVU422M:
256 		tpg->buffers = 3;
257 		/* fall through */
258 	case V4L2_PIX_FMT_YUV422P:
259 		tpg->vdownsampling[1] = 1;
260 		tpg->vdownsampling[2] = 1;
261 		tpg->hdownsampling[1] = 2;
262 		tpg->hdownsampling[2] = 2;
263 		tpg->planes = 3;
264 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
265 		break;
266 	case V4L2_PIX_FMT_NV16M:
267 	case V4L2_PIX_FMT_NV61M:
268 		tpg->buffers = 2;
269 		/* fall through */
270 	case V4L2_PIX_FMT_NV16:
271 	case V4L2_PIX_FMT_NV61:
272 		tpg->vdownsampling[1] = 1;
273 		tpg->hdownsampling[1] = 1;
274 		tpg->hmask[1] = ~1;
275 		tpg->planes = 2;
276 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
277 		break;
278 	case V4L2_PIX_FMT_NV12M:
279 	case V4L2_PIX_FMT_NV21M:
280 		tpg->buffers = 2;
281 		/* fall through */
282 	case V4L2_PIX_FMT_NV12:
283 	case V4L2_PIX_FMT_NV21:
284 		tpg->vdownsampling[1] = 2;
285 		tpg->hdownsampling[1] = 1;
286 		tpg->hmask[1] = ~1;
287 		tpg->planes = 2;
288 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
289 		break;
290 	case V4L2_PIX_FMT_YUV444M:
291 	case V4L2_PIX_FMT_YVU444M:
292 		tpg->buffers = 3;
293 		tpg->planes = 3;
294 		tpg->vdownsampling[1] = 1;
295 		tpg->vdownsampling[2] = 1;
296 		tpg->hdownsampling[1] = 1;
297 		tpg->hdownsampling[2] = 1;
298 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
299 		break;
300 	case V4L2_PIX_FMT_NV24:
301 	case V4L2_PIX_FMT_NV42:
302 		tpg->vdownsampling[1] = 1;
303 		tpg->hdownsampling[1] = 1;
304 		tpg->planes = 2;
305 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
306 		break;
307 	case V4L2_PIX_FMT_YUYV:
308 	case V4L2_PIX_FMT_UYVY:
309 	case V4L2_PIX_FMT_YVYU:
310 	case V4L2_PIX_FMT_VYUY:
311 		tpg->hmask[0] = ~1;
312 		tpg->color_enc = TGP_COLOR_ENC_YCBCR;
313 		break;
314 	case V4L2_PIX_FMT_HSV24:
315 	case V4L2_PIX_FMT_HSV32:
316 		tpg->color_enc = TGP_COLOR_ENC_HSV;
317 		break;
318 	default:
319 		return false;
320 	}
321 
322 	switch (fourcc) {
323 	case V4L2_PIX_FMT_GREY:
324 	case V4L2_PIX_FMT_RGB332:
325 		tpg->twopixelsize[0] = 2;
326 		break;
327 	case V4L2_PIX_FMT_RGB565:
328 	case V4L2_PIX_FMT_RGB565X:
329 	case V4L2_PIX_FMT_RGB444:
330 	case V4L2_PIX_FMT_XRGB444:
331 	case V4L2_PIX_FMT_ARGB444:
332 	case V4L2_PIX_FMT_RGB555:
333 	case V4L2_PIX_FMT_XRGB555:
334 	case V4L2_PIX_FMT_ARGB555:
335 	case V4L2_PIX_FMT_RGB555X:
336 	case V4L2_PIX_FMT_XRGB555X:
337 	case V4L2_PIX_FMT_ARGB555X:
338 	case V4L2_PIX_FMT_YUYV:
339 	case V4L2_PIX_FMT_UYVY:
340 	case V4L2_PIX_FMT_YVYU:
341 	case V4L2_PIX_FMT_VYUY:
342 	case V4L2_PIX_FMT_YUV444:
343 	case V4L2_PIX_FMT_YUV555:
344 	case V4L2_PIX_FMT_YUV565:
345 	case V4L2_PIX_FMT_Y10:
346 	case V4L2_PIX_FMT_Y12:
347 	case V4L2_PIX_FMT_Y16:
348 	case V4L2_PIX_FMT_Y16_BE:
349 		tpg->twopixelsize[0] = 2 * 2;
350 		break;
351 	case V4L2_PIX_FMT_RGB24:
352 	case V4L2_PIX_FMT_BGR24:
353 	case V4L2_PIX_FMT_HSV24:
354 		tpg->twopixelsize[0] = 2 * 3;
355 		break;
356 	case V4L2_PIX_FMT_BGR666:
357 	case V4L2_PIX_FMT_RGB32:
358 	case V4L2_PIX_FMT_BGR32:
359 	case V4L2_PIX_FMT_XRGB32:
360 	case V4L2_PIX_FMT_XBGR32:
361 	case V4L2_PIX_FMT_ARGB32:
362 	case V4L2_PIX_FMT_ABGR32:
363 	case V4L2_PIX_FMT_YUV32:
364 	case V4L2_PIX_FMT_HSV32:
365 		tpg->twopixelsize[0] = 2 * 4;
366 		break;
367 	case V4L2_PIX_FMT_NV12:
368 	case V4L2_PIX_FMT_NV21:
369 	case V4L2_PIX_FMT_NV12M:
370 	case V4L2_PIX_FMT_NV21M:
371 	case V4L2_PIX_FMT_NV16:
372 	case V4L2_PIX_FMT_NV61:
373 	case V4L2_PIX_FMT_NV16M:
374 	case V4L2_PIX_FMT_NV61M:
375 	case V4L2_PIX_FMT_SBGGR8:
376 	case V4L2_PIX_FMT_SGBRG8:
377 	case V4L2_PIX_FMT_SGRBG8:
378 	case V4L2_PIX_FMT_SRGGB8:
379 		tpg->twopixelsize[0] = 2;
380 		tpg->twopixelsize[1] = 2;
381 		break;
382 	case V4L2_PIX_FMT_SRGGB10:
383 	case V4L2_PIX_FMT_SGRBG10:
384 	case V4L2_PIX_FMT_SGBRG10:
385 	case V4L2_PIX_FMT_SBGGR10:
386 	case V4L2_PIX_FMT_SRGGB12:
387 	case V4L2_PIX_FMT_SGRBG12:
388 	case V4L2_PIX_FMT_SGBRG12:
389 	case V4L2_PIX_FMT_SBGGR12:
390 		tpg->twopixelsize[0] = 4;
391 		tpg->twopixelsize[1] = 4;
392 		break;
393 	case V4L2_PIX_FMT_YUV444M:
394 	case V4L2_PIX_FMT_YVU444M:
395 	case V4L2_PIX_FMT_YUV422M:
396 	case V4L2_PIX_FMT_YVU422M:
397 	case V4L2_PIX_FMT_YUV422P:
398 	case V4L2_PIX_FMT_YUV420:
399 	case V4L2_PIX_FMT_YVU420:
400 	case V4L2_PIX_FMT_YUV420M:
401 	case V4L2_PIX_FMT_YVU420M:
402 		tpg->twopixelsize[0] = 2;
403 		tpg->twopixelsize[1] = 2;
404 		tpg->twopixelsize[2] = 2;
405 		break;
406 	case V4L2_PIX_FMT_NV24:
407 	case V4L2_PIX_FMT_NV42:
408 		tpg->twopixelsize[0] = 2;
409 		tpg->twopixelsize[1] = 4;
410 		break;
411 	}
412 	return true;
413 }
414 EXPORT_SYMBOL_GPL(tpg_s_fourcc);
415 
416 void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
417 		const struct v4l2_rect *compose)
418 {
419 	tpg->crop = *crop;
420 	tpg->compose = *compose;
421 	tpg->scaled_width = (tpg->src_width * tpg->compose.width +
422 				 tpg->crop.width - 1) / tpg->crop.width;
423 	tpg->scaled_width &= ~1;
424 	if (tpg->scaled_width > tpg->max_line_width)
425 		tpg->scaled_width = tpg->max_line_width;
426 	if (tpg->scaled_width < 2)
427 		tpg->scaled_width = 2;
428 	tpg->recalc_lines = true;
429 }
430 EXPORT_SYMBOL_GPL(tpg_s_crop_compose);
431 
432 void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
433 		       u32 field)
434 {
435 	unsigned p;
436 
437 	tpg->src_width = width;
438 	tpg->src_height = height;
439 	tpg->field = field;
440 	tpg->buf_height = height;
441 	if (V4L2_FIELD_HAS_T_OR_B(field))
442 		tpg->buf_height /= 2;
443 	tpg->scaled_width = width;
444 	tpg->crop.top = tpg->crop.left = 0;
445 	tpg->crop.width = width;
446 	tpg->crop.height = height;
447 	tpg->compose.top = tpg->compose.left = 0;
448 	tpg->compose.width = width;
449 	tpg->compose.height = tpg->buf_height;
450 	for (p = 0; p < tpg->planes; p++)
451 		tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
452 				       (2 * tpg->hdownsampling[p]);
453 	tpg->recalc_square_border = true;
454 }
455 EXPORT_SYMBOL_GPL(tpg_reset_source);
456 
457 static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
458 {
459 	switch (tpg->pattern) {
460 	case TPG_PAT_BLACK:
461 		return TPG_COLOR_100_WHITE;
462 	case TPG_PAT_CSC_COLORBAR:
463 		return TPG_COLOR_CSC_BLACK;
464 	default:
465 		return TPG_COLOR_100_BLACK;
466 	}
467 }
468 
469 static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
470 {
471 	switch (tpg->pattern) {
472 	case TPG_PAT_75_COLORBAR:
473 	case TPG_PAT_CSC_COLORBAR:
474 		return TPG_COLOR_CSC_WHITE;
475 	case TPG_PAT_BLACK:
476 		return TPG_COLOR_100_BLACK;
477 	default:
478 		return TPG_COLOR_100_WHITE;
479 	}
480 }
481 
482 static inline int rec709_to_linear(int v)
483 {
484 	v = clamp(v, 0, 0xff0);
485 	return tpg_rec709_to_linear[v];
486 }
487 
488 static inline int linear_to_rec709(int v)
489 {
490 	v = clamp(v, 0, 0xff0);
491 	return tpg_linear_to_rec709[v];
492 }
493 
494 static void color_to_hsv(struct tpg_data *tpg, int r, int g, int b,
495 			   int *h, int *s, int *v)
496 {
497 	int max_rgb, min_rgb, diff_rgb;
498 	int aux;
499 	int third;
500 	int third_size;
501 
502 	r >>= 4;
503 	g >>= 4;
504 	b >>= 4;
505 
506 	/* Value */
507 	max_rgb = max3(r, g, b);
508 	*v = max_rgb;
509 	if (!max_rgb) {
510 		*h = 0;
511 		*s = 0;
512 		return;
513 	}
514 
515 	/* Saturation */
516 	min_rgb = min3(r, g, b);
517 	diff_rgb = max_rgb - min_rgb;
518 	aux = 255 * diff_rgb;
519 	aux += max_rgb / 2;
520 	aux /= max_rgb;
521 	*s = aux;
522 	if (!aux) {
523 		*h = 0;
524 		return;
525 	}
526 
527 	third_size = (tpg->real_hsv_enc == V4L2_HSV_ENC_180) ? 60 : 85;
528 
529 	/* Hue */
530 	if (max_rgb == r) {
531 		aux =  g - b;
532 		third = 0;
533 	} else if (max_rgb == g) {
534 		aux =  b - r;
535 		third = third_size;
536 	} else {
537 		aux =  r - g;
538 		third = third_size * 2;
539 	}
540 
541 	aux *= third_size / 2;
542 	aux += diff_rgb / 2;
543 	aux /= diff_rgb;
544 	aux += third;
545 
546 	/* Clamp Hue */
547 	if (tpg->real_hsv_enc == V4L2_HSV_ENC_180) {
548 		if (aux < 0)
549 			aux += 180;
550 		else if (aux > 180)
551 			aux -= 180;
552 	} else {
553 		aux = aux & 0xff;
554 	}
555 
556 	*h = aux;
557 }
558 
559 static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
560 			int y_offset, int *y, int *cb, int *cr)
561 {
562 	*y  = ((m[0][0] * r + m[0][1] * g + m[0][2] * b) >> 16) + (y_offset << 4);
563 	*cb = ((m[1][0] * r + m[1][1] * g + m[1][2] * b) >> 16) + (128 << 4);
564 	*cr = ((m[2][0] * r + m[2][1] * g + m[2][2] * b) >> 16) + (128 << 4);
565 }
566 
567 static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
568 			   int *y, int *cb, int *cr)
569 {
570 #define COEFF(v, r) ((int)(0.5 + (v) * (r) * 256.0))
571 
572 	static const int bt601[3][3] = {
573 		{ COEFF(0.299, 219),   COEFF(0.587, 219),   COEFF(0.114, 219)   },
574 		{ COEFF(-0.1687, 224), COEFF(-0.3313, 224), COEFF(0.5, 224)     },
575 		{ COEFF(0.5, 224),     COEFF(-0.4187, 224), COEFF(-0.0813, 224) },
576 	};
577 	static const int bt601_full[3][3] = {
578 		{ COEFF(0.299, 255),   COEFF(0.587, 255),   COEFF(0.114, 255)   },
579 		{ COEFF(-0.1687, 255), COEFF(-0.3313, 255), COEFF(0.5, 255)     },
580 		{ COEFF(0.5, 255),     COEFF(-0.4187, 255), COEFF(-0.0813, 255) },
581 	};
582 	static const int rec709[3][3] = {
583 		{ COEFF(0.2126, 219),  COEFF(0.7152, 219),  COEFF(0.0722, 219)  },
584 		{ COEFF(-0.1146, 224), COEFF(-0.3854, 224), COEFF(0.5, 224)     },
585 		{ COEFF(0.5, 224),     COEFF(-0.4542, 224), COEFF(-0.0458, 224) },
586 	};
587 	static const int rec709_full[3][3] = {
588 		{ COEFF(0.2126, 255),  COEFF(0.7152, 255),  COEFF(0.0722, 255)  },
589 		{ COEFF(-0.1146, 255), COEFF(-0.3854, 255), COEFF(0.5, 255)     },
590 		{ COEFF(0.5, 255),     COEFF(-0.4542, 255), COEFF(-0.0458, 255) },
591 	};
592 	static const int smpte240m[3][3] = {
593 		{ COEFF(0.212, 219),  COEFF(0.701, 219),  COEFF(0.087, 219)  },
594 		{ COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224)    },
595 		{ COEFF(0.5, 224),    COEFF(-0.445, 224), COEFF(-0.055, 224) },
596 	};
597 	static const int smpte240m_full[3][3] = {
598 		{ COEFF(0.212, 255),  COEFF(0.701, 255),  COEFF(0.087, 255)  },
599 		{ COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255)    },
600 		{ COEFF(0.5, 255),    COEFF(-0.445, 255), COEFF(-0.055, 255) },
601 	};
602 	static const int bt2020[3][3] = {
603 		{ COEFF(0.2627, 219),  COEFF(0.6780, 219),  COEFF(0.0593, 219)  },
604 		{ COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224)     },
605 		{ COEFF(0.5, 224),     COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
606 	};
607 	static const int bt2020_full[3][3] = {
608 		{ COEFF(0.2627, 255),  COEFF(0.6780, 255),  COEFF(0.0593, 255)  },
609 		{ COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255)     },
610 		{ COEFF(0.5, 255),     COEFF(-0.4598, 255), COEFF(-0.0402, 255) },
611 	};
612 	static const int bt2020c[4] = {
613 		COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224),
614 		COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224),
615 	};
616 	static const int bt2020c_full[4] = {
617 		COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255),
618 		COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255),
619 	};
620 
621 	bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
622 	unsigned y_offset = full ? 0 : 16;
623 	int lin_y, yc;
624 
625 	switch (tpg->real_ycbcr_enc) {
626 	case V4L2_YCBCR_ENC_601:
627 		rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr);
628 		break;
629 	case V4L2_YCBCR_ENC_XV601:
630 		/* Ignore quantization range, there is only one possible
631 		 * Y'CbCr encoding. */
632 		rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr);
633 		break;
634 	case V4L2_YCBCR_ENC_XV709:
635 		/* Ignore quantization range, there is only one possible
636 		 * Y'CbCr encoding. */
637 		rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr);
638 		break;
639 	case V4L2_YCBCR_ENC_BT2020:
640 		rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr);
641 		break;
642 	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
643 		lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) +
644 			 COEFF(0.6780, 255) * rec709_to_linear(g) +
645 			 COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16;
646 		yc = linear_to_rec709(lin_y);
647 		*y = full ? yc : (yc * 219) / 255 + (16 << 4);
648 		if (b <= yc)
649 			*cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4);
650 		else
651 			*cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4);
652 		if (r <= yc)
653 			*cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4);
654 		else
655 			*cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4);
656 		break;
657 	case V4L2_YCBCR_ENC_SMPTE240M:
658 		rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr);
659 		break;
660 	case V4L2_YCBCR_ENC_709:
661 	default:
662 		rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr);
663 		break;
664 	}
665 }
666 
667 static void ycbcr2rgb(const int m[3][3], int y, int cb, int cr,
668 			int y_offset, int *r, int *g, int *b)
669 {
670 	y -= y_offset << 4;
671 	cb -= 128 << 4;
672 	cr -= 128 << 4;
673 	*r = m[0][0] * y + m[0][1] * cb + m[0][2] * cr;
674 	*g = m[1][0] * y + m[1][1] * cb + m[1][2] * cr;
675 	*b = m[2][0] * y + m[2][1] * cb + m[2][2] * cr;
676 	*r = clamp(*r >> 12, 0, 0xff0);
677 	*g = clamp(*g >> 12, 0, 0xff0);
678 	*b = clamp(*b >> 12, 0, 0xff0);
679 }
680 
681 static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
682 			   int *r, int *g, int *b)
683 {
684 #undef COEFF
685 #define COEFF(v, r) ((int)(0.5 + (v) * ((255.0 * 255.0 * 16.0) / (r))))
686 	static const int bt601[3][3] = {
687 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.4020, 224)  },
688 		{ COEFF(1, 219), COEFF(-0.3441, 224), COEFF(-0.7141, 224) },
689 		{ COEFF(1, 219), COEFF(1.7720, 224),  COEFF(0, 224)       },
690 	};
691 	static const int bt601_full[3][3] = {
692 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.4020, 255)  },
693 		{ COEFF(1, 255), COEFF(-0.3441, 255), COEFF(-0.7141, 255) },
694 		{ COEFF(1, 255), COEFF(1.7720, 255),  COEFF(0, 255)       },
695 	};
696 	static const int rec709[3][3] = {
697 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.5748, 224)  },
698 		{ COEFF(1, 219), COEFF(-0.1873, 224), COEFF(-0.4681, 224) },
699 		{ COEFF(1, 219), COEFF(1.8556, 224),  COEFF(0, 224)       },
700 	};
701 	static const int rec709_full[3][3] = {
702 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.5748, 255)  },
703 		{ COEFF(1, 255), COEFF(-0.1873, 255), COEFF(-0.4681, 255) },
704 		{ COEFF(1, 255), COEFF(1.8556, 255),  COEFF(0, 255)       },
705 	};
706 	static const int smpte240m[3][3] = {
707 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.5756, 224)  },
708 		{ COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) },
709 		{ COEFF(1, 219), COEFF(1.8270, 224),  COEFF(0, 224)       },
710 	};
711 	static const int smpte240m_full[3][3] = {
712 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.5756, 255)  },
713 		{ COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) },
714 		{ COEFF(1, 255), COEFF(1.8270, 255),  COEFF(0, 255)       },
715 	};
716 	static const int bt2020[3][3] = {
717 		{ COEFF(1, 219), COEFF(0, 224),       COEFF(1.4746, 224)  },
718 		{ COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) },
719 		{ COEFF(1, 219), COEFF(1.8814, 224),  COEFF(0, 224)       },
720 	};
721 	static const int bt2020_full[3][3] = {
722 		{ COEFF(1, 255), COEFF(0, 255),       COEFF(1.4746, 255)  },
723 		{ COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) },
724 		{ COEFF(1, 255), COEFF(1.8814, 255),  COEFF(0, 255)       },
725 	};
726 	static const int bt2020c[4] = {
727 		COEFF(1.9404, 224), COEFF(1.5816, 224),
728 		COEFF(1.7184, 224), COEFF(0.9936, 224),
729 	};
730 	static const int bt2020c_full[4] = {
731 		COEFF(1.9404, 255), COEFF(1.5816, 255),
732 		COEFF(1.7184, 255), COEFF(0.9936, 255),
733 	};
734 
735 	bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
736 	unsigned y_offset = full ? 0 : 16;
737 	int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219);
738 	int lin_r, lin_g, lin_b, lin_y;
739 
740 	switch (tpg->real_ycbcr_enc) {
741 	case V4L2_YCBCR_ENC_601:
742 		ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b);
743 		break;
744 	case V4L2_YCBCR_ENC_XV601:
745 		/* Ignore quantization range, there is only one possible
746 		 * Y'CbCr encoding. */
747 		ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b);
748 		break;
749 	case V4L2_YCBCR_ENC_XV709:
750 		/* Ignore quantization range, there is only one possible
751 		 * Y'CbCr encoding. */
752 		ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b);
753 		break;
754 	case V4L2_YCBCR_ENC_BT2020:
755 		ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b);
756 		break;
757 	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
758 		y -= full ? 0 : 16 << 4;
759 		cb -= 128 << 4;
760 		cr -= 128 << 4;
761 
762 		if (cb <= 0)
763 			*b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb;
764 		else
765 			*b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb;
766 		*b = *b >> 12;
767 		if (cr <= 0)
768 			*r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr;
769 		else
770 			*r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr;
771 		*r = *r >> 12;
772 		lin_r = rec709_to_linear(*r);
773 		lin_b = rec709_to_linear(*b);
774 		lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219));
775 
776 		lin_g = COEFF(1.0 / 0.6780, 255) * lin_y -
777 			COEFF(0.2627 / 0.6780, 255) * lin_r -
778 			COEFF(0.0593 / 0.6780, 255) * lin_b;
779 		*g = linear_to_rec709(lin_g >> 12);
780 		break;
781 	case V4L2_YCBCR_ENC_SMPTE240M:
782 		ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b);
783 		break;
784 	case V4L2_YCBCR_ENC_709:
785 	default:
786 		ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b);
787 		break;
788 	}
789 }
790 
791 /* precalculate color bar values to speed up rendering */
792 static void precalculate_color(struct tpg_data *tpg, int k)
793 {
794 	int col = k;
795 	int r = tpg_colors[col].r;
796 	int g = tpg_colors[col].g;
797 	int b = tpg_colors[col].b;
798 	int y, cb, cr;
799 	bool ycbcr_valid = false;
800 
801 	if (k == TPG_COLOR_TEXTBG) {
802 		col = tpg_get_textbg_color(tpg);
803 
804 		r = tpg_colors[col].r;
805 		g = tpg_colors[col].g;
806 		b = tpg_colors[col].b;
807 	} else if (k == TPG_COLOR_TEXTFG) {
808 		col = tpg_get_textfg_color(tpg);
809 
810 		r = tpg_colors[col].r;
811 		g = tpg_colors[col].g;
812 		b = tpg_colors[col].b;
813 	} else if (tpg->pattern == TPG_PAT_NOISE) {
814 		r = g = b = prandom_u32_max(256);
815 	} else if (k == TPG_COLOR_RANDOM) {
816 		r = g = b = tpg->qual_offset + prandom_u32_max(196);
817 	} else if (k >= TPG_COLOR_RAMP) {
818 		r = g = b = k - TPG_COLOR_RAMP;
819 	}
820 
821 	if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
822 		r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
823 		g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
824 		b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
825 	} else {
826 		r <<= 4;
827 		g <<= 4;
828 		b <<= 4;
829 	}
830 
831 	if (tpg->qual == TPG_QUAL_GRAY ||
832 	    tpg->color_enc ==  TGP_COLOR_ENC_LUMA) {
833 		/* Rec. 709 Luma function */
834 		/* (0.2126, 0.7152, 0.0722) * (255 * 256) */
835 		r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
836 	}
837 
838 	/*
839 	 * The assumption is that the RGB output is always full range,
840 	 * so only if the rgb_range overrides the 'real' rgb range do
841 	 * we need to convert the RGB values.
842 	 *
843 	 * Remember that r, g and b are still in the 0 - 0xff0 range.
844 	 */
845 	if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
846 	    tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL &&
847 	    tpg->color_enc == TGP_COLOR_ENC_RGB) {
848 		/*
849 		 * Convert from full range (which is what r, g and b are)
850 		 * to limited range (which is the 'real' RGB range), which
851 		 * is then interpreted as full range.
852 		 */
853 		r = (r * 219) / 255 + (16 << 4);
854 		g = (g * 219) / 255 + (16 << 4);
855 		b = (b * 219) / 255 + (16 << 4);
856 	} else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
857 		   tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
858 		   tpg->color_enc == TGP_COLOR_ENC_RGB) {
859 
860 		/*
861 		 * Clamp r, g and b to the limited range and convert to full
862 		 * range since that's what we deliver.
863 		 */
864 		r = clamp(r, 16 << 4, 235 << 4);
865 		g = clamp(g, 16 << 4, 235 << 4);
866 		b = clamp(b, 16 << 4, 235 << 4);
867 		r = (r - (16 << 4)) * 255 / 219;
868 		g = (g - (16 << 4)) * 255 / 219;
869 		b = (b - (16 << 4)) * 255 / 219;
870 	}
871 
872 	if ((tpg->brightness != 128 || tpg->contrast != 128 ||
873 	     tpg->saturation != 128 || tpg->hue) &&
874 	    tpg->color_enc != TGP_COLOR_ENC_LUMA) {
875 		/* Implement these operations */
876 		int tmp_cb, tmp_cr;
877 
878 		/* First convert to YCbCr */
879 
880 		color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
881 
882 		y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
883 		y += (tpg->brightness << 4) - (128 << 4);
884 
885 		cb -= 128 << 4;
886 		cr -= 128 << 4;
887 		tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
888 		tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
889 
890 		cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
891 		cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
892 		if (tpg->color_enc == TGP_COLOR_ENC_YCBCR)
893 			ycbcr_valid = true;
894 		else
895 			ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
896 	} else if ((tpg->brightness != 128 || tpg->contrast != 128) &&
897 		   tpg->color_enc == TGP_COLOR_ENC_LUMA) {
898 		r = (16 << 4) + ((r - (16 << 4)) * tpg->contrast) / 128;
899 		r += (tpg->brightness << 4) - (128 << 4);
900 	}
901 
902 	switch (tpg->color_enc) {
903 	case TGP_COLOR_ENC_HSV:
904 	{
905 		int h, s, v;
906 
907 		color_to_hsv(tpg, r, g, b, &h, &s, &v);
908 		tpg->colors[k][0] = h;
909 		tpg->colors[k][1] = s;
910 		tpg->colors[k][2] = v;
911 		break;
912 	}
913 	case TGP_COLOR_ENC_YCBCR:
914 	{
915 		/* Convert to YCbCr */
916 		if (!ycbcr_valid)
917 			color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
918 
919 		y >>= 4;
920 		cb >>= 4;
921 		cr >>= 4;
922 		/*
923 		 * XV601/709 use the header/footer margins to encode R', G'
924 		 * and B' values outside the range [0-1]. So do not clamp
925 		 * XV601/709 values.
926 		 */
927 		if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE &&
928 		    tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV601 &&
929 		    tpg->real_ycbcr_enc != V4L2_YCBCR_ENC_XV709) {
930 			y = clamp(y, 16, 235);
931 			cb = clamp(cb, 16, 240);
932 			cr = clamp(cr, 16, 240);
933 		} else {
934 			y = clamp(y, 1, 254);
935 			cb = clamp(cb, 1, 254);
936 			cr = clamp(cr, 1, 254);
937 		}
938 		switch (tpg->fourcc) {
939 		case V4L2_PIX_FMT_YUV444:
940 			y >>= 4;
941 			cb >>= 4;
942 			cr >>= 4;
943 			break;
944 		case V4L2_PIX_FMT_YUV555:
945 			y >>= 3;
946 			cb >>= 3;
947 			cr >>= 3;
948 			break;
949 		case V4L2_PIX_FMT_YUV565:
950 			y >>= 3;
951 			cb >>= 2;
952 			cr >>= 3;
953 			break;
954 		}
955 		tpg->colors[k][0] = y;
956 		tpg->colors[k][1] = cb;
957 		tpg->colors[k][2] = cr;
958 		break;
959 	}
960 	case TGP_COLOR_ENC_LUMA:
961 	{
962 		tpg->colors[k][0] = r >> 4;
963 		break;
964 	}
965 	case TGP_COLOR_ENC_RGB:
966 	{
967 		if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
968 			r = (r * 219) / 255 + (16 << 4);
969 			g = (g * 219) / 255 + (16 << 4);
970 			b = (b * 219) / 255 + (16 << 4);
971 		}
972 		switch (tpg->fourcc) {
973 		case V4L2_PIX_FMT_RGB332:
974 			r >>= 9;
975 			g >>= 9;
976 			b >>= 10;
977 			break;
978 		case V4L2_PIX_FMT_RGB565:
979 		case V4L2_PIX_FMT_RGB565X:
980 			r >>= 7;
981 			g >>= 6;
982 			b >>= 7;
983 			break;
984 		case V4L2_PIX_FMT_RGB444:
985 		case V4L2_PIX_FMT_XRGB444:
986 		case V4L2_PIX_FMT_ARGB444:
987 			r >>= 8;
988 			g >>= 8;
989 			b >>= 8;
990 			break;
991 		case V4L2_PIX_FMT_RGB555:
992 		case V4L2_PIX_FMT_XRGB555:
993 		case V4L2_PIX_FMT_ARGB555:
994 		case V4L2_PIX_FMT_RGB555X:
995 		case V4L2_PIX_FMT_XRGB555X:
996 		case V4L2_PIX_FMT_ARGB555X:
997 			r >>= 7;
998 			g >>= 7;
999 			b >>= 7;
1000 			break;
1001 		case V4L2_PIX_FMT_BGR666:
1002 			r >>= 6;
1003 			g >>= 6;
1004 			b >>= 6;
1005 			break;
1006 		default:
1007 			r >>= 4;
1008 			g >>= 4;
1009 			b >>= 4;
1010 			break;
1011 		}
1012 
1013 		tpg->colors[k][0] = r;
1014 		tpg->colors[k][1] = g;
1015 		tpg->colors[k][2] = b;
1016 		break;
1017 	}
1018 	}
1019 }
1020 
1021 static void tpg_precalculate_colors(struct tpg_data *tpg)
1022 {
1023 	int k;
1024 
1025 	for (k = 0; k < TPG_COLOR_MAX; k++)
1026 		precalculate_color(tpg, k);
1027 }
1028 
1029 /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
1030 static void gen_twopix(struct tpg_data *tpg,
1031 		u8 buf[TPG_MAX_PLANES][8], int color, bool odd)
1032 {
1033 	unsigned offset = odd * tpg->twopixelsize[0] / 2;
1034 	u8 alpha = tpg->alpha_component;
1035 	u8 r_y_h, g_u_s, b_v;
1036 
1037 	if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
1038 				   color != TPG_COLOR_100_RED &&
1039 				   color != TPG_COLOR_75_RED)
1040 		alpha = 0;
1041 	if (color == TPG_COLOR_RANDOM)
1042 		precalculate_color(tpg, color);
1043 	r_y_h = tpg->colors[color][0]; /* R or precalculated Y, H */
1044 	g_u_s = tpg->colors[color][1]; /* G or precalculated U, V */
1045 	b_v = tpg->colors[color][2]; /* B or precalculated V */
1046 
1047 	switch (tpg->fourcc) {
1048 	case V4L2_PIX_FMT_GREY:
1049 		buf[0][offset] = r_y_h;
1050 		break;
1051 	case V4L2_PIX_FMT_Y10:
1052 		buf[0][offset] = (r_y_h << 2) & 0xff;
1053 		buf[0][offset+1] = r_y_h >> 6;
1054 		break;
1055 	case V4L2_PIX_FMT_Y12:
1056 		buf[0][offset] = (r_y_h << 4) & 0xff;
1057 		buf[0][offset+1] = r_y_h >> 4;
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) % 8] = 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) % 8] = 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