cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

v4l2-tpg-core.c (75962B)


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