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