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