162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * v4l2-tpg.h - Test Pattern Generator 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _V4L2_TPG_H_ 962306a36Sopenharmony_ci#define _V4L2_TPG_H_ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci#include <linux/errno.h> 1362306a36Sopenharmony_ci#include <linux/random.h> 1462306a36Sopenharmony_ci#include <linux/slab.h> 1562306a36Sopenharmony_ci#include <linux/vmalloc.h> 1662306a36Sopenharmony_ci#include <linux/videodev2.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistruct tpg_rbg_color8 { 1962306a36Sopenharmony_ci unsigned char r, g, b; 2062306a36Sopenharmony_ci}; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistruct tpg_rbg_color16 { 2362306a36Sopenharmony_ci __u16 r, g, b; 2462306a36Sopenharmony_ci}; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cienum tpg_color { 2762306a36Sopenharmony_ci TPG_COLOR_CSC_WHITE, 2862306a36Sopenharmony_ci TPG_COLOR_CSC_YELLOW, 2962306a36Sopenharmony_ci TPG_COLOR_CSC_CYAN, 3062306a36Sopenharmony_ci TPG_COLOR_CSC_GREEN, 3162306a36Sopenharmony_ci TPG_COLOR_CSC_MAGENTA, 3262306a36Sopenharmony_ci TPG_COLOR_CSC_RED, 3362306a36Sopenharmony_ci TPG_COLOR_CSC_BLUE, 3462306a36Sopenharmony_ci TPG_COLOR_CSC_BLACK, 3562306a36Sopenharmony_ci TPG_COLOR_75_YELLOW, 3662306a36Sopenharmony_ci TPG_COLOR_75_CYAN, 3762306a36Sopenharmony_ci TPG_COLOR_75_GREEN, 3862306a36Sopenharmony_ci TPG_COLOR_75_MAGENTA, 3962306a36Sopenharmony_ci TPG_COLOR_75_RED, 4062306a36Sopenharmony_ci TPG_COLOR_75_BLUE, 4162306a36Sopenharmony_ci TPG_COLOR_100_WHITE, 4262306a36Sopenharmony_ci TPG_COLOR_100_YELLOW, 4362306a36Sopenharmony_ci TPG_COLOR_100_CYAN, 4462306a36Sopenharmony_ci TPG_COLOR_100_GREEN, 4562306a36Sopenharmony_ci TPG_COLOR_100_MAGENTA, 4662306a36Sopenharmony_ci TPG_COLOR_100_RED, 4762306a36Sopenharmony_ci TPG_COLOR_100_BLUE, 4862306a36Sopenharmony_ci TPG_COLOR_100_BLACK, 4962306a36Sopenharmony_ci TPG_COLOR_TEXTFG, 5062306a36Sopenharmony_ci TPG_COLOR_TEXTBG, 5162306a36Sopenharmony_ci TPG_COLOR_RANDOM, 5262306a36Sopenharmony_ci TPG_COLOR_RAMP, 5362306a36Sopenharmony_ci TPG_COLOR_MAX = TPG_COLOR_RAMP + 256 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ciextern const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX]; 5762306a36Sopenharmony_ciextern const unsigned short tpg_rec709_to_linear[255 * 16 + 1]; 5862306a36Sopenharmony_ciextern const unsigned short tpg_linear_to_rec709[255 * 16 + 1]; 5962306a36Sopenharmony_ciextern const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1] 6062306a36Sopenharmony_ci [V4L2_XFER_FUNC_SMPTE2084 + 1] 6162306a36Sopenharmony_ci [TPG_COLOR_CSC_BLACK + 1]; 6262306a36Sopenharmony_cienum tpg_pattern { 6362306a36Sopenharmony_ci TPG_PAT_75_COLORBAR, 6462306a36Sopenharmony_ci TPG_PAT_100_COLORBAR, 6562306a36Sopenharmony_ci TPG_PAT_CSC_COLORBAR, 6662306a36Sopenharmony_ci TPG_PAT_100_HCOLORBAR, 6762306a36Sopenharmony_ci TPG_PAT_100_COLORSQUARES, 6862306a36Sopenharmony_ci TPG_PAT_BLACK, 6962306a36Sopenharmony_ci TPG_PAT_WHITE, 7062306a36Sopenharmony_ci TPG_PAT_RED, 7162306a36Sopenharmony_ci TPG_PAT_GREEN, 7262306a36Sopenharmony_ci TPG_PAT_BLUE, 7362306a36Sopenharmony_ci TPG_PAT_CHECKERS_16X16, 7462306a36Sopenharmony_ci TPG_PAT_CHECKERS_2X2, 7562306a36Sopenharmony_ci TPG_PAT_CHECKERS_1X1, 7662306a36Sopenharmony_ci TPG_PAT_COLOR_CHECKERS_2X2, 7762306a36Sopenharmony_ci TPG_PAT_COLOR_CHECKERS_1X1, 7862306a36Sopenharmony_ci TPG_PAT_ALTERNATING_HLINES, 7962306a36Sopenharmony_ci TPG_PAT_ALTERNATING_VLINES, 8062306a36Sopenharmony_ci TPG_PAT_CROSS_1_PIXEL, 8162306a36Sopenharmony_ci TPG_PAT_CROSS_2_PIXELS, 8262306a36Sopenharmony_ci TPG_PAT_CROSS_10_PIXELS, 8362306a36Sopenharmony_ci TPG_PAT_GRAY_RAMP, 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci /* Must be the last pattern */ 8662306a36Sopenharmony_ci TPG_PAT_NOISE, 8762306a36Sopenharmony_ci}; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciextern const char * const tpg_pattern_strings[]; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cienum tpg_quality { 9262306a36Sopenharmony_ci TPG_QUAL_COLOR, 9362306a36Sopenharmony_ci TPG_QUAL_GRAY, 9462306a36Sopenharmony_ci TPG_QUAL_NOISE 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cienum tpg_video_aspect { 9862306a36Sopenharmony_ci TPG_VIDEO_ASPECT_IMAGE, 9962306a36Sopenharmony_ci TPG_VIDEO_ASPECT_4X3, 10062306a36Sopenharmony_ci TPG_VIDEO_ASPECT_14X9_CENTRE, 10162306a36Sopenharmony_ci TPG_VIDEO_ASPECT_16X9_CENTRE, 10262306a36Sopenharmony_ci TPG_VIDEO_ASPECT_16X9_ANAMORPHIC, 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cienum tpg_pixel_aspect { 10662306a36Sopenharmony_ci TPG_PIXEL_ASPECT_SQUARE, 10762306a36Sopenharmony_ci TPG_PIXEL_ASPECT_NTSC, 10862306a36Sopenharmony_ci TPG_PIXEL_ASPECT_PAL, 10962306a36Sopenharmony_ci}; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cienum tpg_move_mode { 11262306a36Sopenharmony_ci TPG_MOVE_NEG_FAST, 11362306a36Sopenharmony_ci TPG_MOVE_NEG, 11462306a36Sopenharmony_ci TPG_MOVE_NEG_SLOW, 11562306a36Sopenharmony_ci TPG_MOVE_NONE, 11662306a36Sopenharmony_ci TPG_MOVE_POS_SLOW, 11762306a36Sopenharmony_ci TPG_MOVE_POS, 11862306a36Sopenharmony_ci TPG_MOVE_POS_FAST, 11962306a36Sopenharmony_ci}; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cienum tgp_color_enc { 12262306a36Sopenharmony_ci TGP_COLOR_ENC_RGB, 12362306a36Sopenharmony_ci TGP_COLOR_ENC_YCBCR, 12462306a36Sopenharmony_ci TGP_COLOR_ENC_HSV, 12562306a36Sopenharmony_ci TGP_COLOR_ENC_LUMA, 12662306a36Sopenharmony_ci}; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciextern const char * const tpg_aspect_strings[]; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#define TPG_MAX_PLANES 3 13162306a36Sopenharmony_ci#define TPG_MAX_PAT_LINES 8 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistruct tpg_data { 13462306a36Sopenharmony_ci /* Source frame size */ 13562306a36Sopenharmony_ci unsigned src_width, src_height; 13662306a36Sopenharmony_ci /* Buffer height */ 13762306a36Sopenharmony_ci unsigned buf_height; 13862306a36Sopenharmony_ci /* Scaled output frame size */ 13962306a36Sopenharmony_ci unsigned scaled_width; 14062306a36Sopenharmony_ci u32 field; 14162306a36Sopenharmony_ci bool field_alternate; 14262306a36Sopenharmony_ci /* crop coordinates are frame-based */ 14362306a36Sopenharmony_ci struct v4l2_rect crop; 14462306a36Sopenharmony_ci /* compose coordinates are format-based */ 14562306a36Sopenharmony_ci struct v4l2_rect compose; 14662306a36Sopenharmony_ci /* border and square coordinates are frame-based */ 14762306a36Sopenharmony_ci struct v4l2_rect border; 14862306a36Sopenharmony_ci struct v4l2_rect square; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci /* Color-related fields */ 15162306a36Sopenharmony_ci enum tpg_quality qual; 15262306a36Sopenharmony_ci unsigned qual_offset; 15362306a36Sopenharmony_ci u8 alpha_component; 15462306a36Sopenharmony_ci bool alpha_red_only; 15562306a36Sopenharmony_ci u8 brightness; 15662306a36Sopenharmony_ci u8 contrast; 15762306a36Sopenharmony_ci u8 saturation; 15862306a36Sopenharmony_ci s16 hue; 15962306a36Sopenharmony_ci u32 fourcc; 16062306a36Sopenharmony_ci enum tgp_color_enc color_enc; 16162306a36Sopenharmony_ci u32 colorspace; 16262306a36Sopenharmony_ci u32 xfer_func; 16362306a36Sopenharmony_ci u32 ycbcr_enc; 16462306a36Sopenharmony_ci u32 hsv_enc; 16562306a36Sopenharmony_ci /* 16662306a36Sopenharmony_ci * Stores the actual transfer function, i.e. will never be 16762306a36Sopenharmony_ci * V4L2_XFER_FUNC_DEFAULT. 16862306a36Sopenharmony_ci */ 16962306a36Sopenharmony_ci u32 real_xfer_func; 17062306a36Sopenharmony_ci /* 17162306a36Sopenharmony_ci * Stores the actual Y'CbCr encoding, i.e. will never be 17262306a36Sopenharmony_ci * V4L2_YCBCR_ENC_DEFAULT. 17362306a36Sopenharmony_ci */ 17462306a36Sopenharmony_ci u32 real_hsv_enc; 17562306a36Sopenharmony_ci u32 real_ycbcr_enc; 17662306a36Sopenharmony_ci u32 quantization; 17762306a36Sopenharmony_ci /* 17862306a36Sopenharmony_ci * Stores the actual quantization, i.e. will never be 17962306a36Sopenharmony_ci * V4L2_QUANTIZATION_DEFAULT. 18062306a36Sopenharmony_ci */ 18162306a36Sopenharmony_ci u32 real_quantization; 18262306a36Sopenharmony_ci enum tpg_video_aspect vid_aspect; 18362306a36Sopenharmony_ci enum tpg_pixel_aspect pix_aspect; 18462306a36Sopenharmony_ci unsigned rgb_range; 18562306a36Sopenharmony_ci unsigned real_rgb_range; 18662306a36Sopenharmony_ci unsigned buffers; 18762306a36Sopenharmony_ci unsigned planes; 18862306a36Sopenharmony_ci bool interleaved; 18962306a36Sopenharmony_ci u8 vdownsampling[TPG_MAX_PLANES]; 19062306a36Sopenharmony_ci u8 hdownsampling[TPG_MAX_PLANES]; 19162306a36Sopenharmony_ci /* 19262306a36Sopenharmony_ci * horizontal positions must be ANDed with this value to enforce 19362306a36Sopenharmony_ci * correct boundaries for packed YUYV values. 19462306a36Sopenharmony_ci */ 19562306a36Sopenharmony_ci unsigned hmask[TPG_MAX_PLANES]; 19662306a36Sopenharmony_ci /* Used to store the colors in native format, either RGB or YUV */ 19762306a36Sopenharmony_ci u8 colors[TPG_COLOR_MAX][3]; 19862306a36Sopenharmony_ci u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8]; 19962306a36Sopenharmony_ci /* size in bytes for two pixels in each plane */ 20062306a36Sopenharmony_ci unsigned twopixelsize[TPG_MAX_PLANES]; 20162306a36Sopenharmony_ci unsigned bytesperline[TPG_MAX_PLANES]; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci /* Configuration */ 20462306a36Sopenharmony_ci enum tpg_pattern pattern; 20562306a36Sopenharmony_ci bool hflip; 20662306a36Sopenharmony_ci bool vflip; 20762306a36Sopenharmony_ci unsigned perc_fill; 20862306a36Sopenharmony_ci bool perc_fill_blank; 20962306a36Sopenharmony_ci bool show_border; 21062306a36Sopenharmony_ci bool show_square; 21162306a36Sopenharmony_ci bool insert_sav; 21262306a36Sopenharmony_ci bool insert_eav; 21362306a36Sopenharmony_ci bool insert_hdmi_video_guard_band; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci /* Test pattern movement */ 21662306a36Sopenharmony_ci enum tpg_move_mode mv_hor_mode; 21762306a36Sopenharmony_ci int mv_hor_count; 21862306a36Sopenharmony_ci int mv_hor_step; 21962306a36Sopenharmony_ci enum tpg_move_mode mv_vert_mode; 22062306a36Sopenharmony_ci int mv_vert_count; 22162306a36Sopenharmony_ci int mv_vert_step; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci bool recalc_colors; 22462306a36Sopenharmony_ci bool recalc_lines; 22562306a36Sopenharmony_ci bool recalc_square_border; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ 22862306a36Sopenharmony_ci unsigned max_line_width; 22962306a36Sopenharmony_ci u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; 23062306a36Sopenharmony_ci u8 *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; 23162306a36Sopenharmony_ci u8 *random_line[TPG_MAX_PLANES]; 23262306a36Sopenharmony_ci u8 *contrast_line[TPG_MAX_PLANES]; 23362306a36Sopenharmony_ci u8 *black_line[TPG_MAX_PLANES]; 23462306a36Sopenharmony_ci}; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_civoid tpg_init(struct tpg_data *tpg, unsigned w, unsigned h); 23762306a36Sopenharmony_ciint tpg_alloc(struct tpg_data *tpg, unsigned max_w); 23862306a36Sopenharmony_civoid tpg_free(struct tpg_data *tpg); 23962306a36Sopenharmony_civoid tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height, 24062306a36Sopenharmony_ci u32 field); 24162306a36Sopenharmony_civoid tpg_log_status(struct tpg_data *tpg); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_civoid tpg_set_font(const u8 *f); 24462306a36Sopenharmony_civoid tpg_gen_text(const struct tpg_data *tpg, 24562306a36Sopenharmony_ci u8 *basep[TPG_MAX_PLANES][2], int y, int x, const char *text); 24662306a36Sopenharmony_civoid tpg_calc_text_basep(struct tpg_data *tpg, 24762306a36Sopenharmony_ci u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); 24862306a36Sopenharmony_ciunsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line); 24962306a36Sopenharmony_civoid tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std, 25062306a36Sopenharmony_ci unsigned p, u8 *vbuf); 25162306a36Sopenharmony_civoid tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, 25262306a36Sopenharmony_ci unsigned p, u8 *vbuf); 25362306a36Sopenharmony_cibool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc); 25462306a36Sopenharmony_civoid tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop, 25562306a36Sopenharmony_ci const struct v4l2_rect *compose); 25662306a36Sopenharmony_ciconst char *tpg_g_color_order(const struct tpg_data *tpg); 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_cistatic inline void tpg_s_pattern(struct tpg_data *tpg, enum tpg_pattern pattern) 25962306a36Sopenharmony_ci{ 26062306a36Sopenharmony_ci if (tpg->pattern == pattern) 26162306a36Sopenharmony_ci return; 26262306a36Sopenharmony_ci tpg->pattern = pattern; 26362306a36Sopenharmony_ci tpg->recalc_colors = true; 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic inline void tpg_s_quality(struct tpg_data *tpg, 26762306a36Sopenharmony_ci enum tpg_quality qual, unsigned qual_offset) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci if (tpg->qual == qual && tpg->qual_offset == qual_offset) 27062306a36Sopenharmony_ci return; 27162306a36Sopenharmony_ci tpg->qual = qual; 27262306a36Sopenharmony_ci tpg->qual_offset = qual_offset; 27362306a36Sopenharmony_ci tpg->recalc_colors = true; 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistatic inline enum tpg_quality tpg_g_quality(const struct tpg_data *tpg) 27762306a36Sopenharmony_ci{ 27862306a36Sopenharmony_ci return tpg->qual; 27962306a36Sopenharmony_ci} 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistatic inline void tpg_s_alpha_component(struct tpg_data *tpg, 28262306a36Sopenharmony_ci u8 alpha_component) 28362306a36Sopenharmony_ci{ 28462306a36Sopenharmony_ci if (tpg->alpha_component == alpha_component) 28562306a36Sopenharmony_ci return; 28662306a36Sopenharmony_ci tpg->alpha_component = alpha_component; 28762306a36Sopenharmony_ci tpg->recalc_colors = true; 28862306a36Sopenharmony_ci} 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cistatic inline void tpg_s_alpha_mode(struct tpg_data *tpg, 29162306a36Sopenharmony_ci bool red_only) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci if (tpg->alpha_red_only == red_only) 29462306a36Sopenharmony_ci return; 29562306a36Sopenharmony_ci tpg->alpha_red_only = red_only; 29662306a36Sopenharmony_ci tpg->recalc_colors = true; 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_cistatic inline void tpg_s_brightness(struct tpg_data *tpg, 30062306a36Sopenharmony_ci u8 brightness) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci if (tpg->brightness == brightness) 30362306a36Sopenharmony_ci return; 30462306a36Sopenharmony_ci tpg->brightness = brightness; 30562306a36Sopenharmony_ci tpg->recalc_colors = true; 30662306a36Sopenharmony_ci} 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_cistatic inline void tpg_s_contrast(struct tpg_data *tpg, 30962306a36Sopenharmony_ci u8 contrast) 31062306a36Sopenharmony_ci{ 31162306a36Sopenharmony_ci if (tpg->contrast == contrast) 31262306a36Sopenharmony_ci return; 31362306a36Sopenharmony_ci tpg->contrast = contrast; 31462306a36Sopenharmony_ci tpg->recalc_colors = true; 31562306a36Sopenharmony_ci} 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_cistatic inline void tpg_s_saturation(struct tpg_data *tpg, 31862306a36Sopenharmony_ci u8 saturation) 31962306a36Sopenharmony_ci{ 32062306a36Sopenharmony_ci if (tpg->saturation == saturation) 32162306a36Sopenharmony_ci return; 32262306a36Sopenharmony_ci tpg->saturation = saturation; 32362306a36Sopenharmony_ci tpg->recalc_colors = true; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_cistatic inline void tpg_s_hue(struct tpg_data *tpg, 32762306a36Sopenharmony_ci s16 hue) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci hue = clamp_t(s16, hue, -128, 128); 33062306a36Sopenharmony_ci if (tpg->hue == hue) 33162306a36Sopenharmony_ci return; 33262306a36Sopenharmony_ci tpg->hue = hue; 33362306a36Sopenharmony_ci tpg->recalc_colors = true; 33462306a36Sopenharmony_ci} 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_cistatic inline void tpg_s_rgb_range(struct tpg_data *tpg, 33762306a36Sopenharmony_ci unsigned rgb_range) 33862306a36Sopenharmony_ci{ 33962306a36Sopenharmony_ci if (tpg->rgb_range == rgb_range) 34062306a36Sopenharmony_ci return; 34162306a36Sopenharmony_ci tpg->rgb_range = rgb_range; 34262306a36Sopenharmony_ci tpg->recalc_colors = true; 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic inline void tpg_s_real_rgb_range(struct tpg_data *tpg, 34662306a36Sopenharmony_ci unsigned rgb_range) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci if (tpg->real_rgb_range == rgb_range) 34962306a36Sopenharmony_ci return; 35062306a36Sopenharmony_ci tpg->real_rgb_range = rgb_range; 35162306a36Sopenharmony_ci tpg->recalc_colors = true; 35262306a36Sopenharmony_ci} 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_cistatic inline void tpg_s_colorspace(struct tpg_data *tpg, u32 colorspace) 35562306a36Sopenharmony_ci{ 35662306a36Sopenharmony_ci if (tpg->colorspace == colorspace) 35762306a36Sopenharmony_ci return; 35862306a36Sopenharmony_ci tpg->colorspace = colorspace; 35962306a36Sopenharmony_ci tpg->recalc_colors = true; 36062306a36Sopenharmony_ci} 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic inline u32 tpg_g_colorspace(const struct tpg_data *tpg) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci return tpg->colorspace; 36562306a36Sopenharmony_ci} 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_cistatic inline void tpg_s_ycbcr_enc(struct tpg_data *tpg, u32 ycbcr_enc) 36862306a36Sopenharmony_ci{ 36962306a36Sopenharmony_ci if (tpg->ycbcr_enc == ycbcr_enc) 37062306a36Sopenharmony_ci return; 37162306a36Sopenharmony_ci tpg->ycbcr_enc = ycbcr_enc; 37262306a36Sopenharmony_ci tpg->recalc_colors = true; 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic inline u32 tpg_g_ycbcr_enc(const struct tpg_data *tpg) 37662306a36Sopenharmony_ci{ 37762306a36Sopenharmony_ci return tpg->ycbcr_enc; 37862306a36Sopenharmony_ci} 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_cistatic inline void tpg_s_hsv_enc(struct tpg_data *tpg, u32 hsv_enc) 38162306a36Sopenharmony_ci{ 38262306a36Sopenharmony_ci if (tpg->hsv_enc == hsv_enc) 38362306a36Sopenharmony_ci return; 38462306a36Sopenharmony_ci tpg->hsv_enc = hsv_enc; 38562306a36Sopenharmony_ci tpg->recalc_colors = true; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_cistatic inline u32 tpg_g_hsv_enc(const struct tpg_data *tpg) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci return tpg->hsv_enc; 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic inline void tpg_s_xfer_func(struct tpg_data *tpg, u32 xfer_func) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci if (tpg->xfer_func == xfer_func) 39662306a36Sopenharmony_ci return; 39762306a36Sopenharmony_ci tpg->xfer_func = xfer_func; 39862306a36Sopenharmony_ci tpg->recalc_colors = true; 39962306a36Sopenharmony_ci} 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistatic inline u32 tpg_g_xfer_func(const struct tpg_data *tpg) 40262306a36Sopenharmony_ci{ 40362306a36Sopenharmony_ci return tpg->xfer_func; 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_cistatic inline void tpg_s_quantization(struct tpg_data *tpg, u32 quantization) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci if (tpg->quantization == quantization) 40962306a36Sopenharmony_ci return; 41062306a36Sopenharmony_ci tpg->quantization = quantization; 41162306a36Sopenharmony_ci tpg->recalc_colors = true; 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_cistatic inline u32 tpg_g_quantization(const struct tpg_data *tpg) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci return tpg->quantization; 41762306a36Sopenharmony_ci} 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_cistatic inline unsigned tpg_g_buffers(const struct tpg_data *tpg) 42062306a36Sopenharmony_ci{ 42162306a36Sopenharmony_ci return tpg->buffers; 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic inline unsigned tpg_g_planes(const struct tpg_data *tpg) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci return tpg->interleaved ? 1 : tpg->planes; 42762306a36Sopenharmony_ci} 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_cistatic inline bool tpg_g_interleaved(const struct tpg_data *tpg) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci return tpg->interleaved; 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci return tpg->twopixelsize[plane]; 43762306a36Sopenharmony_ci} 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic inline unsigned tpg_hdiv(const struct tpg_data *tpg, 44062306a36Sopenharmony_ci unsigned plane, unsigned x) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) * 44362306a36Sopenharmony_ci tpg->twopixelsize[plane] / 2; 44462306a36Sopenharmony_ci} 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_cistatic inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x) 44762306a36Sopenharmony_ci{ 44862306a36Sopenharmony_ci return (x * tpg->scaled_width) / tpg->src_width; 44962306a36Sopenharmony_ci} 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistatic inline unsigned tpg_hscale_div(const struct tpg_data *tpg, 45262306a36Sopenharmony_ci unsigned plane, unsigned x) 45362306a36Sopenharmony_ci{ 45462306a36Sopenharmony_ci return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x)); 45562306a36Sopenharmony_ci} 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_cistatic inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci return tpg->bytesperline[plane]; 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ci 46262306a36Sopenharmony_cistatic inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci unsigned p; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci if (tpg->buffers > 1) { 46762306a36Sopenharmony_ci tpg->bytesperline[plane] = bpl; 46862306a36Sopenharmony_ci return; 46962306a36Sopenharmony_ci } 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci for (p = 0; p < tpg_g_planes(tpg); p++) { 47262306a36Sopenharmony_ci unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p]; 47562306a36Sopenharmony_ci } 47662306a36Sopenharmony_ci if (tpg_g_interleaved(tpg)) 47762306a36Sopenharmony_ci tpg->bytesperline[1] = tpg->bytesperline[0]; 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane) 48262306a36Sopenharmony_ci{ 48362306a36Sopenharmony_ci unsigned w = 0; 48462306a36Sopenharmony_ci unsigned p; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci if (tpg->buffers > 1) 48762306a36Sopenharmony_ci return tpg_g_bytesperline(tpg, plane); 48862306a36Sopenharmony_ci for (p = 0; p < tpg_g_planes(tpg); p++) { 48962306a36Sopenharmony_ci unsigned plane_w = tpg_g_bytesperline(tpg, p); 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci w += plane_w / tpg->vdownsampling[p]; 49262306a36Sopenharmony_ci } 49362306a36Sopenharmony_ci return w; 49462306a36Sopenharmony_ci} 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic inline unsigned tpg_calc_line_width(const struct tpg_data *tpg, 49762306a36Sopenharmony_ci unsigned plane, unsigned bpl) 49862306a36Sopenharmony_ci{ 49962306a36Sopenharmony_ci unsigned w = 0; 50062306a36Sopenharmony_ci unsigned p; 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci if (tpg->buffers > 1) 50362306a36Sopenharmony_ci return bpl; 50462306a36Sopenharmony_ci for (p = 0; p < tpg_g_planes(tpg); p++) { 50562306a36Sopenharmony_ci unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0]; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci plane_w /= tpg->hdownsampling[p]; 50862306a36Sopenharmony_ci w += plane_w / tpg->vdownsampling[p]; 50962306a36Sopenharmony_ci } 51062306a36Sopenharmony_ci return w; 51162306a36Sopenharmony_ci} 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cistatic inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane) 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci if (plane >= tpg_g_planes(tpg)) 51662306a36Sopenharmony_ci return 0; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci return tpg_g_bytesperline(tpg, plane) * tpg->buf_height / 51962306a36Sopenharmony_ci tpg->vdownsampling[plane]; 52062306a36Sopenharmony_ci} 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_cistatic inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) 52362306a36Sopenharmony_ci{ 52462306a36Sopenharmony_ci tpg->buf_height = h; 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_cistatic inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate) 52862306a36Sopenharmony_ci{ 52962306a36Sopenharmony_ci tpg->field = field; 53062306a36Sopenharmony_ci tpg->field_alternate = alternate; 53162306a36Sopenharmony_ci} 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_cistatic inline void tpg_s_perc_fill(struct tpg_data *tpg, 53462306a36Sopenharmony_ci unsigned perc_fill) 53562306a36Sopenharmony_ci{ 53662306a36Sopenharmony_ci tpg->perc_fill = perc_fill; 53762306a36Sopenharmony_ci} 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_cistatic inline unsigned tpg_g_perc_fill(const struct tpg_data *tpg) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci return tpg->perc_fill; 54262306a36Sopenharmony_ci} 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_cistatic inline void tpg_s_perc_fill_blank(struct tpg_data *tpg, 54562306a36Sopenharmony_ci bool perc_fill_blank) 54662306a36Sopenharmony_ci{ 54762306a36Sopenharmony_ci tpg->perc_fill_blank = perc_fill_blank; 54862306a36Sopenharmony_ci} 54962306a36Sopenharmony_ci 55062306a36Sopenharmony_cistatic inline void tpg_s_video_aspect(struct tpg_data *tpg, 55162306a36Sopenharmony_ci enum tpg_video_aspect vid_aspect) 55262306a36Sopenharmony_ci{ 55362306a36Sopenharmony_ci if (tpg->vid_aspect == vid_aspect) 55462306a36Sopenharmony_ci return; 55562306a36Sopenharmony_ci tpg->vid_aspect = vid_aspect; 55662306a36Sopenharmony_ci tpg->recalc_square_border = true; 55762306a36Sopenharmony_ci} 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cistatic inline enum tpg_video_aspect tpg_g_video_aspect(const struct tpg_data *tpg) 56062306a36Sopenharmony_ci{ 56162306a36Sopenharmony_ci return tpg->vid_aspect; 56262306a36Sopenharmony_ci} 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_cistatic inline void tpg_s_pixel_aspect(struct tpg_data *tpg, 56562306a36Sopenharmony_ci enum tpg_pixel_aspect pix_aspect) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci if (tpg->pix_aspect == pix_aspect) 56862306a36Sopenharmony_ci return; 56962306a36Sopenharmony_ci tpg->pix_aspect = pix_aspect; 57062306a36Sopenharmony_ci tpg->recalc_square_border = true; 57162306a36Sopenharmony_ci} 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_cistatic inline void tpg_s_show_border(struct tpg_data *tpg, 57462306a36Sopenharmony_ci bool show_border) 57562306a36Sopenharmony_ci{ 57662306a36Sopenharmony_ci tpg->show_border = show_border; 57762306a36Sopenharmony_ci} 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_cistatic inline void tpg_s_show_square(struct tpg_data *tpg, 58062306a36Sopenharmony_ci bool show_square) 58162306a36Sopenharmony_ci{ 58262306a36Sopenharmony_ci tpg->show_square = show_square; 58362306a36Sopenharmony_ci} 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cistatic inline void tpg_s_insert_sav(struct tpg_data *tpg, bool insert_sav) 58662306a36Sopenharmony_ci{ 58762306a36Sopenharmony_ci tpg->insert_sav = insert_sav; 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_cistatic inline void tpg_s_insert_eav(struct tpg_data *tpg, bool insert_eav) 59162306a36Sopenharmony_ci{ 59262306a36Sopenharmony_ci tpg->insert_eav = insert_eav; 59362306a36Sopenharmony_ci} 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci/* 59662306a36Sopenharmony_ci * This inserts 4 pixels of the RGB color 0xab55ab at the left hand side of the 59762306a36Sopenharmony_ci * image. This is only done for 3 or 4 byte RGB pixel formats. This pixel value 59862306a36Sopenharmony_ci * equals the Video Guard Band value as defined by HDMI (see section 5.2.2.1 59962306a36Sopenharmony_ci * in the HDMI 1.3 Specification) that preceeds the first actual pixel. If the 60062306a36Sopenharmony_ci * HDMI receiver doesn't handle this correctly, then it might keep skipping 60162306a36Sopenharmony_ci * these Video Guard Band patterns and end up with a shorter video line. So this 60262306a36Sopenharmony_ci * is a nice pattern to test with. 60362306a36Sopenharmony_ci */ 60462306a36Sopenharmony_cistatic inline void tpg_s_insert_hdmi_video_guard_band(struct tpg_data *tpg, 60562306a36Sopenharmony_ci bool insert_hdmi_video_guard_band) 60662306a36Sopenharmony_ci{ 60762306a36Sopenharmony_ci tpg->insert_hdmi_video_guard_band = insert_hdmi_video_guard_band; 60862306a36Sopenharmony_ci} 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_civoid tpg_update_mv_step(struct tpg_data *tpg); 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_cistatic inline void tpg_s_mv_hor_mode(struct tpg_data *tpg, 61362306a36Sopenharmony_ci enum tpg_move_mode mv_hor_mode) 61462306a36Sopenharmony_ci{ 61562306a36Sopenharmony_ci tpg->mv_hor_mode = mv_hor_mode; 61662306a36Sopenharmony_ci tpg_update_mv_step(tpg); 61762306a36Sopenharmony_ci} 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_cistatic inline void tpg_s_mv_vert_mode(struct tpg_data *tpg, 62062306a36Sopenharmony_ci enum tpg_move_mode mv_vert_mode) 62162306a36Sopenharmony_ci{ 62262306a36Sopenharmony_ci tpg->mv_vert_mode = mv_vert_mode; 62362306a36Sopenharmony_ci tpg_update_mv_step(tpg); 62462306a36Sopenharmony_ci} 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_cistatic inline void tpg_init_mv_count(struct tpg_data *tpg) 62762306a36Sopenharmony_ci{ 62862306a36Sopenharmony_ci tpg->mv_hor_count = tpg->mv_vert_count = 0; 62962306a36Sopenharmony_ci} 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_cistatic inline void tpg_update_mv_count(struct tpg_data *tpg, bool frame_is_field) 63262306a36Sopenharmony_ci{ 63362306a36Sopenharmony_ci tpg->mv_hor_count += tpg->mv_hor_step * (frame_is_field ? 1 : 2); 63462306a36Sopenharmony_ci tpg->mv_vert_count += tpg->mv_vert_step * (frame_is_field ? 1 : 2); 63562306a36Sopenharmony_ci} 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_cistatic inline void tpg_s_hflip(struct tpg_data *tpg, bool hflip) 63862306a36Sopenharmony_ci{ 63962306a36Sopenharmony_ci if (tpg->hflip == hflip) 64062306a36Sopenharmony_ci return; 64162306a36Sopenharmony_ci tpg->hflip = hflip; 64262306a36Sopenharmony_ci tpg_update_mv_step(tpg); 64362306a36Sopenharmony_ci tpg->recalc_lines = true; 64462306a36Sopenharmony_ci} 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_cistatic inline bool tpg_g_hflip(const struct tpg_data *tpg) 64762306a36Sopenharmony_ci{ 64862306a36Sopenharmony_ci return tpg->hflip; 64962306a36Sopenharmony_ci} 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_cistatic inline void tpg_s_vflip(struct tpg_data *tpg, bool vflip) 65262306a36Sopenharmony_ci{ 65362306a36Sopenharmony_ci tpg->vflip = vflip; 65462306a36Sopenharmony_ci} 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_cistatic inline bool tpg_g_vflip(const struct tpg_data *tpg) 65762306a36Sopenharmony_ci{ 65862306a36Sopenharmony_ci return tpg->vflip; 65962306a36Sopenharmony_ci} 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_cistatic inline bool tpg_pattern_is_static(const struct tpg_data *tpg) 66262306a36Sopenharmony_ci{ 66362306a36Sopenharmony_ci return tpg->pattern != TPG_PAT_NOISE && 66462306a36Sopenharmony_ci tpg->mv_hor_mode == TPG_MOVE_NONE && 66562306a36Sopenharmony_ci tpg->mv_vert_mode == TPG_MOVE_NONE; 66662306a36Sopenharmony_ci} 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci#endif 669