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