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-dv-timings.c (34158B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * v4l2-dv-timings - dv-timings helper functions
      4 *
      5 * Copyright 2013 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/types.h>
     10#include <linux/kernel.h>
     11#include <linux/errno.h>
     12#include <linux/rational.h>
     13#include <linux/videodev2.h>
     14#include <linux/v4l2-dv-timings.h>
     15#include <media/v4l2-dv-timings.h>
     16#include <linux/math64.h>
     17#include <linux/hdmi.h>
     18#include <media/cec.h>
     19
     20MODULE_AUTHOR("Hans Verkuil");
     21MODULE_DESCRIPTION("V4L2 DV Timings Helper Functions");
     22MODULE_LICENSE("GPL");
     23
     24const struct v4l2_dv_timings v4l2_dv_timings_presets[] = {
     25	V4L2_DV_BT_CEA_640X480P59_94,
     26	V4L2_DV_BT_CEA_720X480I59_94,
     27	V4L2_DV_BT_CEA_720X480P59_94,
     28	V4L2_DV_BT_CEA_720X576I50,
     29	V4L2_DV_BT_CEA_720X576P50,
     30	V4L2_DV_BT_CEA_1280X720P24,
     31	V4L2_DV_BT_CEA_1280X720P25,
     32	V4L2_DV_BT_CEA_1280X720P30,
     33	V4L2_DV_BT_CEA_1280X720P50,
     34	V4L2_DV_BT_CEA_1280X720P60,
     35	V4L2_DV_BT_CEA_1920X1080P24,
     36	V4L2_DV_BT_CEA_1920X1080P25,
     37	V4L2_DV_BT_CEA_1920X1080P30,
     38	V4L2_DV_BT_CEA_1920X1080I50,
     39	V4L2_DV_BT_CEA_1920X1080P50,
     40	V4L2_DV_BT_CEA_1920X1080I60,
     41	V4L2_DV_BT_CEA_1920X1080P60,
     42	V4L2_DV_BT_DMT_640X350P85,
     43	V4L2_DV_BT_DMT_640X400P85,
     44	V4L2_DV_BT_DMT_720X400P85,
     45	V4L2_DV_BT_DMT_640X480P72,
     46	V4L2_DV_BT_DMT_640X480P75,
     47	V4L2_DV_BT_DMT_640X480P85,
     48	V4L2_DV_BT_DMT_800X600P56,
     49	V4L2_DV_BT_DMT_800X600P60,
     50	V4L2_DV_BT_DMT_800X600P72,
     51	V4L2_DV_BT_DMT_800X600P75,
     52	V4L2_DV_BT_DMT_800X600P85,
     53	V4L2_DV_BT_DMT_800X600P120_RB,
     54	V4L2_DV_BT_DMT_848X480P60,
     55	V4L2_DV_BT_DMT_1024X768I43,
     56	V4L2_DV_BT_DMT_1024X768P60,
     57	V4L2_DV_BT_DMT_1024X768P70,
     58	V4L2_DV_BT_DMT_1024X768P75,
     59	V4L2_DV_BT_DMT_1024X768P85,
     60	V4L2_DV_BT_DMT_1024X768P120_RB,
     61	V4L2_DV_BT_DMT_1152X864P75,
     62	V4L2_DV_BT_DMT_1280X768P60_RB,
     63	V4L2_DV_BT_DMT_1280X768P60,
     64	V4L2_DV_BT_DMT_1280X768P75,
     65	V4L2_DV_BT_DMT_1280X768P85,
     66	V4L2_DV_BT_DMT_1280X768P120_RB,
     67	V4L2_DV_BT_DMT_1280X800P60_RB,
     68	V4L2_DV_BT_DMT_1280X800P60,
     69	V4L2_DV_BT_DMT_1280X800P75,
     70	V4L2_DV_BT_DMT_1280X800P85,
     71	V4L2_DV_BT_DMT_1280X800P120_RB,
     72	V4L2_DV_BT_DMT_1280X960P60,
     73	V4L2_DV_BT_DMT_1280X960P85,
     74	V4L2_DV_BT_DMT_1280X960P120_RB,
     75	V4L2_DV_BT_DMT_1280X1024P60,
     76	V4L2_DV_BT_DMT_1280X1024P75,
     77	V4L2_DV_BT_DMT_1280X1024P85,
     78	V4L2_DV_BT_DMT_1280X1024P120_RB,
     79	V4L2_DV_BT_DMT_1360X768P60,
     80	V4L2_DV_BT_DMT_1360X768P120_RB,
     81	V4L2_DV_BT_DMT_1366X768P60,
     82	V4L2_DV_BT_DMT_1366X768P60_RB,
     83	V4L2_DV_BT_DMT_1400X1050P60_RB,
     84	V4L2_DV_BT_DMT_1400X1050P60,
     85	V4L2_DV_BT_DMT_1400X1050P75,
     86	V4L2_DV_BT_DMT_1400X1050P85,
     87	V4L2_DV_BT_DMT_1400X1050P120_RB,
     88	V4L2_DV_BT_DMT_1440X900P60_RB,
     89	V4L2_DV_BT_DMT_1440X900P60,
     90	V4L2_DV_BT_DMT_1440X900P75,
     91	V4L2_DV_BT_DMT_1440X900P85,
     92	V4L2_DV_BT_DMT_1440X900P120_RB,
     93	V4L2_DV_BT_DMT_1600X900P60_RB,
     94	V4L2_DV_BT_DMT_1600X1200P60,
     95	V4L2_DV_BT_DMT_1600X1200P65,
     96	V4L2_DV_BT_DMT_1600X1200P70,
     97	V4L2_DV_BT_DMT_1600X1200P75,
     98	V4L2_DV_BT_DMT_1600X1200P85,
     99	V4L2_DV_BT_DMT_1600X1200P120_RB,
    100	V4L2_DV_BT_DMT_1680X1050P60_RB,
    101	V4L2_DV_BT_DMT_1680X1050P60,
    102	V4L2_DV_BT_DMT_1680X1050P75,
    103	V4L2_DV_BT_DMT_1680X1050P85,
    104	V4L2_DV_BT_DMT_1680X1050P120_RB,
    105	V4L2_DV_BT_DMT_1792X1344P60,
    106	V4L2_DV_BT_DMT_1792X1344P75,
    107	V4L2_DV_BT_DMT_1792X1344P120_RB,
    108	V4L2_DV_BT_DMT_1856X1392P60,
    109	V4L2_DV_BT_DMT_1856X1392P75,
    110	V4L2_DV_BT_DMT_1856X1392P120_RB,
    111	V4L2_DV_BT_DMT_1920X1200P60_RB,
    112	V4L2_DV_BT_DMT_1920X1200P60,
    113	V4L2_DV_BT_DMT_1920X1200P75,
    114	V4L2_DV_BT_DMT_1920X1200P85,
    115	V4L2_DV_BT_DMT_1920X1200P120_RB,
    116	V4L2_DV_BT_DMT_1920X1440P60,
    117	V4L2_DV_BT_DMT_1920X1440P75,
    118	V4L2_DV_BT_DMT_1920X1440P120_RB,
    119	V4L2_DV_BT_DMT_2048X1152P60_RB,
    120	V4L2_DV_BT_DMT_2560X1600P60_RB,
    121	V4L2_DV_BT_DMT_2560X1600P60,
    122	V4L2_DV_BT_DMT_2560X1600P75,
    123	V4L2_DV_BT_DMT_2560X1600P85,
    124	V4L2_DV_BT_DMT_2560X1600P120_RB,
    125	V4L2_DV_BT_CEA_3840X2160P24,
    126	V4L2_DV_BT_CEA_3840X2160P25,
    127	V4L2_DV_BT_CEA_3840X2160P30,
    128	V4L2_DV_BT_CEA_3840X2160P50,
    129	V4L2_DV_BT_CEA_3840X2160P60,
    130	V4L2_DV_BT_CEA_4096X2160P24,
    131	V4L2_DV_BT_CEA_4096X2160P25,
    132	V4L2_DV_BT_CEA_4096X2160P30,
    133	V4L2_DV_BT_CEA_4096X2160P50,
    134	V4L2_DV_BT_DMT_4096X2160P59_94_RB,
    135	V4L2_DV_BT_CEA_4096X2160P60,
    136	{ }
    137};
    138EXPORT_SYMBOL_GPL(v4l2_dv_timings_presets);
    139
    140bool v4l2_valid_dv_timings(const struct v4l2_dv_timings *t,
    141			   const struct v4l2_dv_timings_cap *dvcap,
    142			   v4l2_check_dv_timings_fnc fnc,
    143			   void *fnc_handle)
    144{
    145	const struct v4l2_bt_timings *bt = &t->bt;
    146	const struct v4l2_bt_timings_cap *cap = &dvcap->bt;
    147	u32 caps = cap->capabilities;
    148
    149	if (t->type != V4L2_DV_BT_656_1120)
    150		return false;
    151	if (t->type != dvcap->type ||
    152	    bt->height < cap->min_height ||
    153	    bt->height > cap->max_height ||
    154	    bt->width < cap->min_width ||
    155	    bt->width > cap->max_width ||
    156	    bt->pixelclock < cap->min_pixelclock ||
    157	    bt->pixelclock > cap->max_pixelclock ||
    158	    (!(caps & V4L2_DV_BT_CAP_CUSTOM) &&
    159	     cap->standards && bt->standards &&
    160	     !(bt->standards & cap->standards)) ||
    161	    (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
    162	    (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
    163		return false;
    164	return fnc == NULL || fnc(t, fnc_handle);
    165}
    166EXPORT_SYMBOL_GPL(v4l2_valid_dv_timings);
    167
    168int v4l2_enum_dv_timings_cap(struct v4l2_enum_dv_timings *t,
    169			     const struct v4l2_dv_timings_cap *cap,
    170			     v4l2_check_dv_timings_fnc fnc,
    171			     void *fnc_handle)
    172{
    173	u32 i, idx;
    174
    175	memset(t->reserved, 0, sizeof(t->reserved));
    176	for (i = idx = 0; v4l2_dv_timings_presets[i].bt.width; i++) {
    177		if (v4l2_valid_dv_timings(v4l2_dv_timings_presets + i, cap,
    178					  fnc, fnc_handle) &&
    179		    idx++ == t->index) {
    180			t->timings = v4l2_dv_timings_presets[i];
    181			return 0;
    182		}
    183	}
    184	return -EINVAL;
    185}
    186EXPORT_SYMBOL_GPL(v4l2_enum_dv_timings_cap);
    187
    188bool v4l2_find_dv_timings_cap(struct v4l2_dv_timings *t,
    189			      const struct v4l2_dv_timings_cap *cap,
    190			      unsigned pclock_delta,
    191			      v4l2_check_dv_timings_fnc fnc,
    192			      void *fnc_handle)
    193{
    194	int i;
    195
    196	if (!v4l2_valid_dv_timings(t, cap, fnc, fnc_handle))
    197		return false;
    198
    199	for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) {
    200		if (v4l2_valid_dv_timings(v4l2_dv_timings_presets + i, cap,
    201					  fnc, fnc_handle) &&
    202		    v4l2_match_dv_timings(t, v4l2_dv_timings_presets + i,
    203					  pclock_delta, false)) {
    204			u32 flags = t->bt.flags & V4L2_DV_FL_REDUCED_FPS;
    205
    206			*t = v4l2_dv_timings_presets[i];
    207			if (can_reduce_fps(&t->bt))
    208				t->bt.flags |= flags;
    209
    210			return true;
    211		}
    212	}
    213	return false;
    214}
    215EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cap);
    216
    217bool v4l2_find_dv_timings_cea861_vic(struct v4l2_dv_timings *t, u8 vic)
    218{
    219	unsigned int i;
    220
    221	for (i = 0; v4l2_dv_timings_presets[i].bt.width; i++) {
    222		const struct v4l2_bt_timings *bt =
    223			&v4l2_dv_timings_presets[i].bt;
    224
    225		if ((bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) &&
    226		    bt->cea861_vic == vic) {
    227			*t = v4l2_dv_timings_presets[i];
    228			return true;
    229		}
    230	}
    231	return false;
    232}
    233EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cea861_vic);
    234
    235/**
    236 * v4l2_match_dv_timings - check if two timings match
    237 * @t1: compare this v4l2_dv_timings struct...
    238 * @t2: with this struct.
    239 * @pclock_delta: the allowed pixelclock deviation.
    240 * @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
    241 *	match.
    242 *
    243 * Compare t1 with t2 with a given margin of error for the pixelclock.
    244 */
    245bool v4l2_match_dv_timings(const struct v4l2_dv_timings *t1,
    246			   const struct v4l2_dv_timings *t2,
    247			   unsigned pclock_delta, bool match_reduced_fps)
    248{
    249	if (t1->type != t2->type || t1->type != V4L2_DV_BT_656_1120)
    250		return false;
    251	if (t1->bt.width == t2->bt.width &&
    252	    t1->bt.height == t2->bt.height &&
    253	    t1->bt.interlaced == t2->bt.interlaced &&
    254	    t1->bt.polarities == t2->bt.polarities &&
    255	    t1->bt.pixelclock >= t2->bt.pixelclock - pclock_delta &&
    256	    t1->bt.pixelclock <= t2->bt.pixelclock + pclock_delta &&
    257	    t1->bt.hfrontporch == t2->bt.hfrontporch &&
    258	    t1->bt.hsync == t2->bt.hsync &&
    259	    t1->bt.hbackporch == t2->bt.hbackporch &&
    260	    t1->bt.vfrontporch == t2->bt.vfrontporch &&
    261	    t1->bt.vsync == t2->bt.vsync &&
    262	    t1->bt.vbackporch == t2->bt.vbackporch &&
    263	    (!match_reduced_fps ||
    264	     (t1->bt.flags & V4L2_DV_FL_REDUCED_FPS) ==
    265		(t2->bt.flags & V4L2_DV_FL_REDUCED_FPS)) &&
    266	    (!t1->bt.interlaced ||
    267		(t1->bt.il_vfrontporch == t2->bt.il_vfrontporch &&
    268		 t1->bt.il_vsync == t2->bt.il_vsync &&
    269		 t1->bt.il_vbackporch == t2->bt.il_vbackporch)))
    270		return true;
    271	return false;
    272}
    273EXPORT_SYMBOL_GPL(v4l2_match_dv_timings);
    274
    275void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix,
    276			   const struct v4l2_dv_timings *t, bool detailed)
    277{
    278	const struct v4l2_bt_timings *bt = &t->bt;
    279	u32 htot, vtot;
    280	u32 fps;
    281
    282	if (t->type != V4L2_DV_BT_656_1120)
    283		return;
    284
    285	htot = V4L2_DV_BT_FRAME_WIDTH(bt);
    286	vtot = V4L2_DV_BT_FRAME_HEIGHT(bt);
    287	if (bt->interlaced)
    288		vtot /= 2;
    289
    290	fps = (htot * vtot) > 0 ? div_u64((100 * (u64)bt->pixelclock),
    291				  (htot * vtot)) : 0;
    292
    293	if (prefix == NULL)
    294		prefix = "";
    295
    296	pr_info("%s: %s%ux%u%s%u.%02u (%ux%u)\n", dev_prefix, prefix,
    297		bt->width, bt->height, bt->interlaced ? "i" : "p",
    298		fps / 100, fps % 100, htot, vtot);
    299
    300	if (!detailed)
    301		return;
    302
    303	pr_info("%s: horizontal: fp = %u, %ssync = %u, bp = %u\n",
    304			dev_prefix, bt->hfrontporch,
    305			(bt->polarities & V4L2_DV_HSYNC_POS_POL) ? "+" : "-",
    306			bt->hsync, bt->hbackporch);
    307	pr_info("%s: vertical: fp = %u, %ssync = %u, bp = %u\n",
    308			dev_prefix, bt->vfrontporch,
    309			(bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
    310			bt->vsync, bt->vbackporch);
    311	if (bt->interlaced)
    312		pr_info("%s: vertical bottom field: fp = %u, %ssync = %u, bp = %u\n",
    313			dev_prefix, bt->il_vfrontporch,
    314			(bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-",
    315			bt->il_vsync, bt->il_vbackporch);
    316	pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock);
    317	pr_info("%s: flags (0x%x):%s%s%s%s%s%s%s%s%s%s\n",
    318			dev_prefix, bt->flags,
    319			(bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ?
    320			" REDUCED_BLANKING" : "",
    321			((bt->flags & V4L2_DV_FL_REDUCED_BLANKING) &&
    322			 bt->vsync == 8) ? " (V2)" : "",
    323			(bt->flags & V4L2_DV_FL_CAN_REDUCE_FPS) ?
    324			" CAN_REDUCE_FPS" : "",
    325			(bt->flags & V4L2_DV_FL_REDUCED_FPS) ?
    326			" REDUCED_FPS" : "",
    327			(bt->flags & V4L2_DV_FL_HALF_LINE) ?
    328			" HALF_LINE" : "",
    329			(bt->flags & V4L2_DV_FL_IS_CE_VIDEO) ?
    330			" CE_VIDEO" : "",
    331			(bt->flags & V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE) ?
    332			" FIRST_FIELD_EXTRA_LINE" : "",
    333			(bt->flags & V4L2_DV_FL_HAS_PICTURE_ASPECT) ?
    334			" HAS_PICTURE_ASPECT" : "",
    335			(bt->flags & V4L2_DV_FL_HAS_CEA861_VIC) ?
    336			" HAS_CEA861_VIC" : "",
    337			(bt->flags & V4L2_DV_FL_HAS_HDMI_VIC) ?
    338			" HAS_HDMI_VIC" : "");
    339	pr_info("%s: standards (0x%x):%s%s%s%s%s\n", dev_prefix, bt->standards,
    340			(bt->standards & V4L2_DV_BT_STD_CEA861) ?  " CEA" : "",
    341			(bt->standards & V4L2_DV_BT_STD_DMT) ?  " DMT" : "",
    342			(bt->standards & V4L2_DV_BT_STD_CVT) ?  " CVT" : "",
    343			(bt->standards & V4L2_DV_BT_STD_GTF) ?  " GTF" : "",
    344			(bt->standards & V4L2_DV_BT_STD_SDI) ?  " SDI" : "");
    345	if (bt->flags & V4L2_DV_FL_HAS_PICTURE_ASPECT)
    346		pr_info("%s: picture aspect (hor:vert): %u:%u\n", dev_prefix,
    347			bt->picture_aspect.numerator,
    348			bt->picture_aspect.denominator);
    349	if (bt->flags & V4L2_DV_FL_HAS_CEA861_VIC)
    350		pr_info("%s: CEA-861 VIC: %u\n", dev_prefix, bt->cea861_vic);
    351	if (bt->flags & V4L2_DV_FL_HAS_HDMI_VIC)
    352		pr_info("%s: HDMI VIC: %u\n", dev_prefix, bt->hdmi_vic);
    353}
    354EXPORT_SYMBOL_GPL(v4l2_print_dv_timings);
    355
    356struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t)
    357{
    358	struct v4l2_fract ratio = { 1, 1 };
    359	unsigned long n, d;
    360
    361	if (t->type != V4L2_DV_BT_656_1120)
    362		return ratio;
    363	if (!(t->bt.flags & V4L2_DV_FL_HAS_PICTURE_ASPECT))
    364		return ratio;
    365
    366	ratio.numerator = t->bt.width * t->bt.picture_aspect.denominator;
    367	ratio.denominator = t->bt.height * t->bt.picture_aspect.numerator;
    368
    369	rational_best_approximation(ratio.numerator, ratio.denominator,
    370				    ratio.numerator, ratio.denominator, &n, &d);
    371	ratio.numerator = n;
    372	ratio.denominator = d;
    373	return ratio;
    374}
    375EXPORT_SYMBOL_GPL(v4l2_dv_timings_aspect_ratio);
    376
    377/** v4l2_calc_timeperframe - helper function to calculate timeperframe based
    378 *	v4l2_dv_timings fields.
    379 * @t - Timings for the video mode.
    380 *
    381 * Calculates the expected timeperframe using the pixel clock value and
    382 * horizontal/vertical measures. This means that v4l2_dv_timings structure
    383 * must be correctly and fully filled.
    384 */
    385struct v4l2_fract v4l2_calc_timeperframe(const struct v4l2_dv_timings *t)
    386{
    387	const struct v4l2_bt_timings *bt = &t->bt;
    388	struct v4l2_fract fps_fract = { 1, 1 };
    389	unsigned long n, d;
    390	u32 htot, vtot, fps;
    391	u64 pclk;
    392
    393	if (t->type != V4L2_DV_BT_656_1120)
    394		return fps_fract;
    395
    396	htot = V4L2_DV_BT_FRAME_WIDTH(bt);
    397	vtot = V4L2_DV_BT_FRAME_HEIGHT(bt);
    398	pclk = bt->pixelclock;
    399
    400	if ((bt->flags & V4L2_DV_FL_CAN_DETECT_REDUCED_FPS) &&
    401	    (bt->flags & V4L2_DV_FL_REDUCED_FPS))
    402		pclk = div_u64(pclk * 1000ULL, 1001);
    403
    404	fps = (htot * vtot) > 0 ? div_u64((100 * pclk), (htot * vtot)) : 0;
    405	if (!fps)
    406		return fps_fract;
    407
    408	rational_best_approximation(fps, 100, fps, 100, &n, &d);
    409
    410	fps_fract.numerator = d;
    411	fps_fract.denominator = n;
    412	return fps_fract;
    413}
    414EXPORT_SYMBOL_GPL(v4l2_calc_timeperframe);
    415
    416/*
    417 * CVT defines
    418 * Based on Coordinated Video Timings Standard
    419 * version 1.1 September 10, 2003
    420 */
    421
    422#define CVT_PXL_CLK_GRAN	250000	/* pixel clock granularity */
    423#define CVT_PXL_CLK_GRAN_RB_V2 1000	/* granularity for reduced blanking v2*/
    424
    425/* Normal blanking */
    426#define CVT_MIN_V_BPORCH	7	/* lines */
    427#define CVT_MIN_V_PORCH_RND	3	/* lines */
    428#define CVT_MIN_VSYNC_BP	550	/* min time of vsync + back porch (us) */
    429#define CVT_HSYNC_PERCENT       8       /* nominal hsync as percentage of line */
    430
    431/* Normal blanking for CVT uses GTF to calculate horizontal blanking */
    432#define CVT_CELL_GRAN		8	/* character cell granularity */
    433#define CVT_M			600	/* blanking formula gradient */
    434#define CVT_C			40	/* blanking formula offset */
    435#define CVT_K			128	/* blanking formula scaling factor */
    436#define CVT_J			20	/* blanking formula scaling factor */
    437#define CVT_C_PRIME (((CVT_C - CVT_J) * CVT_K / 256) + CVT_J)
    438#define CVT_M_PRIME (CVT_K * CVT_M / 256)
    439
    440/* Reduced Blanking */
    441#define CVT_RB_MIN_V_BPORCH    7       /* lines  */
    442#define CVT_RB_V_FPORCH        3       /* lines  */
    443#define CVT_RB_MIN_V_BLANK   460       /* us     */
    444#define CVT_RB_H_SYNC         32       /* pixels */
    445#define CVT_RB_H_BLANK       160       /* pixels */
    446/* Reduce blanking Version 2 */
    447#define CVT_RB_V2_H_BLANK     80       /* pixels */
    448#define CVT_RB_MIN_V_FPORCH    3       /* lines  */
    449#define CVT_RB_V2_MIN_V_FPORCH 1       /* lines  */
    450#define CVT_RB_V_BPORCH        6       /* lines  */
    451
    452/** v4l2_detect_cvt - detect if the given timings follow the CVT standard
    453 * @frame_height - the total height of the frame (including blanking) in lines.
    454 * @hfreq - the horizontal frequency in Hz.
    455 * @vsync - the height of the vertical sync in lines.
    456 * @active_width - active width of image (does not include blanking). This
    457 * information is needed only in case of version 2 of reduced blanking.
    458 * In other cases, this parameter does not have any effect on timings.
    459 * @polarities - the horizontal and vertical polarities (same as struct
    460 *		v4l2_bt_timings polarities).
    461 * @interlaced - if this flag is true, it indicates interlaced format
    462 * @fmt - the resulting timings.
    463 *
    464 * This function will attempt to detect if the given values correspond to a
    465 * valid CVT format. If so, then it will return true, and fmt will be filled
    466 * in with the found CVT timings.
    467 */
    468bool v4l2_detect_cvt(unsigned frame_height,
    469		     unsigned hfreq,
    470		     unsigned vsync,
    471		     unsigned active_width,
    472		     u32 polarities,
    473		     bool interlaced,
    474		     struct v4l2_dv_timings *fmt)
    475{
    476	int  v_fp, v_bp, h_fp, h_bp, hsync;
    477	int  frame_width, image_height, image_width;
    478	bool reduced_blanking;
    479	bool rb_v2 = false;
    480	unsigned pix_clk;
    481
    482	if (vsync < 4 || vsync > 8)
    483		return false;
    484
    485	if (polarities == V4L2_DV_VSYNC_POS_POL)
    486		reduced_blanking = false;
    487	else if (polarities == V4L2_DV_HSYNC_POS_POL)
    488		reduced_blanking = true;
    489	else
    490		return false;
    491
    492	if (reduced_blanking && vsync == 8)
    493		rb_v2 = true;
    494
    495	if (rb_v2 && active_width == 0)
    496		return false;
    497
    498	if (!rb_v2 && vsync > 7)
    499		return false;
    500
    501	if (hfreq == 0)
    502		return false;
    503
    504	/* Vertical */
    505	if (reduced_blanking) {
    506		if (rb_v2) {
    507			v_bp = CVT_RB_V_BPORCH;
    508			v_fp = (CVT_RB_MIN_V_BLANK * hfreq) / 1000000 + 1;
    509			v_fp -= vsync + v_bp;
    510
    511			if (v_fp < CVT_RB_V2_MIN_V_FPORCH)
    512				v_fp = CVT_RB_V2_MIN_V_FPORCH;
    513		} else {
    514			v_fp = CVT_RB_V_FPORCH;
    515			v_bp = (CVT_RB_MIN_V_BLANK * hfreq) / 1000000 + 1;
    516			v_bp -= vsync + v_fp;
    517
    518			if (v_bp < CVT_RB_MIN_V_BPORCH)
    519				v_bp = CVT_RB_MIN_V_BPORCH;
    520		}
    521	} else {
    522		v_fp = CVT_MIN_V_PORCH_RND;
    523		v_bp = (CVT_MIN_VSYNC_BP * hfreq) / 1000000 + 1 - vsync;
    524
    525		if (v_bp < CVT_MIN_V_BPORCH)
    526			v_bp = CVT_MIN_V_BPORCH;
    527	}
    528
    529	if (interlaced)
    530		image_height = (frame_height - 2 * v_fp - 2 * vsync - 2 * v_bp) & ~0x1;
    531	else
    532		image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
    533
    534	if (image_height < 0)
    535		return false;
    536
    537	/* Aspect ratio based on vsync */
    538	switch (vsync) {
    539	case 4:
    540		image_width = (image_height * 4) / 3;
    541		break;
    542	case 5:
    543		image_width = (image_height * 16) / 9;
    544		break;
    545	case 6:
    546		image_width = (image_height * 16) / 10;
    547		break;
    548	case 7:
    549		/* special case */
    550		if (image_height == 1024)
    551			image_width = (image_height * 5) / 4;
    552		else if (image_height == 768)
    553			image_width = (image_height * 15) / 9;
    554		else
    555			return false;
    556		break;
    557	case 8:
    558		image_width = active_width;
    559		break;
    560	default:
    561		return false;
    562	}
    563
    564	if (!rb_v2)
    565		image_width = image_width & ~7;
    566
    567	/* Horizontal */
    568	if (reduced_blanking) {
    569		int h_blank;
    570		int clk_gran;
    571
    572		h_blank = rb_v2 ? CVT_RB_V2_H_BLANK : CVT_RB_H_BLANK;
    573		clk_gran = rb_v2 ? CVT_PXL_CLK_GRAN_RB_V2 : CVT_PXL_CLK_GRAN;
    574
    575		pix_clk = (image_width + h_blank) * hfreq;
    576		pix_clk = (pix_clk / clk_gran) * clk_gran;
    577
    578		h_bp  = h_blank / 2;
    579		hsync = CVT_RB_H_SYNC;
    580		h_fp  = h_blank - h_bp - hsync;
    581
    582		frame_width = image_width + h_blank;
    583	} else {
    584		unsigned ideal_duty_cycle_per_myriad =
    585			100 * CVT_C_PRIME - (CVT_M_PRIME * 100000) / hfreq;
    586		int h_blank;
    587
    588		if (ideal_duty_cycle_per_myriad < 2000)
    589			ideal_duty_cycle_per_myriad = 2000;
    590
    591		h_blank = image_width * ideal_duty_cycle_per_myriad /
    592					(10000 - ideal_duty_cycle_per_myriad);
    593		h_blank = (h_blank / (2 * CVT_CELL_GRAN)) * 2 * CVT_CELL_GRAN;
    594
    595		pix_clk = (image_width + h_blank) * hfreq;
    596		pix_clk = (pix_clk / CVT_PXL_CLK_GRAN) * CVT_PXL_CLK_GRAN;
    597
    598		h_bp = h_blank / 2;
    599		frame_width = image_width + h_blank;
    600
    601		hsync = frame_width * CVT_HSYNC_PERCENT / 100;
    602		hsync = (hsync / CVT_CELL_GRAN) * CVT_CELL_GRAN;
    603		h_fp = h_blank - hsync - h_bp;
    604	}
    605
    606	fmt->type = V4L2_DV_BT_656_1120;
    607	fmt->bt.polarities = polarities;
    608	fmt->bt.width = image_width;
    609	fmt->bt.height = image_height;
    610	fmt->bt.hfrontporch = h_fp;
    611	fmt->bt.vfrontporch = v_fp;
    612	fmt->bt.hsync = hsync;
    613	fmt->bt.vsync = vsync;
    614	fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
    615
    616	if (!interlaced) {
    617		fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
    618		fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
    619	} else {
    620		fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
    621				      2 * vsync) / 2;
    622		fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
    623					2 * vsync - fmt->bt.vbackporch;
    624		fmt->bt.il_vfrontporch = v_fp;
    625		fmt->bt.il_vsync = vsync;
    626		fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
    627		fmt->bt.interlaced = V4L2_DV_INTERLACED;
    628	}
    629
    630	fmt->bt.pixelclock = pix_clk;
    631	fmt->bt.standards = V4L2_DV_BT_STD_CVT;
    632
    633	if (reduced_blanking)
    634		fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
    635
    636	return true;
    637}
    638EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
    639
    640/*
    641 * GTF defines
    642 * Based on Generalized Timing Formula Standard
    643 * Version 1.1 September 2, 1999
    644 */
    645
    646#define GTF_PXL_CLK_GRAN	250000	/* pixel clock granularity */
    647
    648#define GTF_MIN_VSYNC_BP	550	/* min time of vsync + back porch (us) */
    649#define GTF_V_FP		1	/* vertical front porch (lines) */
    650#define GTF_CELL_GRAN		8	/* character cell granularity */
    651
    652/* Default */
    653#define GTF_D_M			600	/* blanking formula gradient */
    654#define GTF_D_C			40	/* blanking formula offset */
    655#define GTF_D_K			128	/* blanking formula scaling factor */
    656#define GTF_D_J			20	/* blanking formula scaling factor */
    657#define GTF_D_C_PRIME ((((GTF_D_C - GTF_D_J) * GTF_D_K) / 256) + GTF_D_J)
    658#define GTF_D_M_PRIME ((GTF_D_K * GTF_D_M) / 256)
    659
    660/* Secondary */
    661#define GTF_S_M			3600	/* blanking formula gradient */
    662#define GTF_S_C			40	/* blanking formula offset */
    663#define GTF_S_K			128	/* blanking formula scaling factor */
    664#define GTF_S_J			35	/* blanking formula scaling factor */
    665#define GTF_S_C_PRIME ((((GTF_S_C - GTF_S_J) * GTF_S_K) / 256) + GTF_S_J)
    666#define GTF_S_M_PRIME ((GTF_S_K * GTF_S_M) / 256)
    667
    668/** v4l2_detect_gtf - detect if the given timings follow the GTF standard
    669 * @frame_height - the total height of the frame (including blanking) in lines.
    670 * @hfreq - the horizontal frequency in Hz.
    671 * @vsync - the height of the vertical sync in lines.
    672 * @polarities - the horizontal and vertical polarities (same as struct
    673 *		v4l2_bt_timings polarities).
    674 * @interlaced - if this flag is true, it indicates interlaced format
    675 * @aspect - preferred aspect ratio. GTF has no method of determining the
    676 *		aspect ratio in order to derive the image width from the
    677 *		image height, so it has to be passed explicitly. Usually
    678 *		the native screen aspect ratio is used for this. If it
    679 *		is not filled in correctly, then 16:9 will be assumed.
    680 * @fmt - the resulting timings.
    681 *
    682 * This function will attempt to detect if the given values correspond to a
    683 * valid GTF format. If so, then it will return true, and fmt will be filled
    684 * in with the found GTF timings.
    685 */
    686bool v4l2_detect_gtf(unsigned frame_height,
    687		unsigned hfreq,
    688		unsigned vsync,
    689		u32 polarities,
    690		bool interlaced,
    691		struct v4l2_fract aspect,
    692		struct v4l2_dv_timings *fmt)
    693{
    694	int pix_clk;
    695	int  v_fp, v_bp, h_fp, hsync;
    696	int frame_width, image_height, image_width;
    697	bool default_gtf;
    698	int h_blank;
    699
    700	if (vsync != 3)
    701		return false;
    702
    703	if (polarities == V4L2_DV_VSYNC_POS_POL)
    704		default_gtf = true;
    705	else if (polarities == V4L2_DV_HSYNC_POS_POL)
    706		default_gtf = false;
    707	else
    708		return false;
    709
    710	if (hfreq == 0)
    711		return false;
    712
    713	/* Vertical */
    714	v_fp = GTF_V_FP;
    715	v_bp = (GTF_MIN_VSYNC_BP * hfreq + 500000) / 1000000 - vsync;
    716	if (interlaced)
    717		image_height = (frame_height - 2 * v_fp - 2 * vsync - 2 * v_bp) & ~0x1;
    718	else
    719		image_height = (frame_height - v_fp - vsync - v_bp + 1) & ~0x1;
    720
    721	if (image_height < 0)
    722		return false;
    723
    724	if (aspect.numerator == 0 || aspect.denominator == 0) {
    725		aspect.numerator = 16;
    726		aspect.denominator = 9;
    727	}
    728	image_width = ((image_height * aspect.numerator) / aspect.denominator);
    729	image_width = (image_width + GTF_CELL_GRAN/2) & ~(GTF_CELL_GRAN - 1);
    730
    731	/* Horizontal */
    732	if (default_gtf) {
    733		u64 num;
    734		u32 den;
    735
    736		num = ((image_width * GTF_D_C_PRIME * (u64)hfreq) -
    737		      ((u64)image_width * GTF_D_M_PRIME * 1000));
    738		den = (hfreq * (100 - GTF_D_C_PRIME) + GTF_D_M_PRIME * 1000) *
    739		      (2 * GTF_CELL_GRAN);
    740		h_blank = div_u64((num + (den >> 1)), den);
    741		h_blank *= (2 * GTF_CELL_GRAN);
    742	} else {
    743		u64 num;
    744		u32 den;
    745
    746		num = ((image_width * GTF_S_C_PRIME * (u64)hfreq) -
    747		      ((u64)image_width * GTF_S_M_PRIME * 1000));
    748		den = (hfreq * (100 - GTF_S_C_PRIME) + GTF_S_M_PRIME * 1000) *
    749		      (2 * GTF_CELL_GRAN);
    750		h_blank = div_u64((num + (den >> 1)), den);
    751		h_blank *= (2 * GTF_CELL_GRAN);
    752	}
    753
    754	frame_width = image_width + h_blank;
    755
    756	pix_clk = (image_width + h_blank) * hfreq;
    757	pix_clk = pix_clk / GTF_PXL_CLK_GRAN * GTF_PXL_CLK_GRAN;
    758
    759	hsync = (frame_width * 8 + 50) / 100;
    760	hsync = DIV_ROUND_CLOSEST(hsync, GTF_CELL_GRAN) * GTF_CELL_GRAN;
    761
    762	h_fp = h_blank / 2 - hsync;
    763
    764	fmt->type = V4L2_DV_BT_656_1120;
    765	fmt->bt.polarities = polarities;
    766	fmt->bt.width = image_width;
    767	fmt->bt.height = image_height;
    768	fmt->bt.hfrontporch = h_fp;
    769	fmt->bt.vfrontporch = v_fp;
    770	fmt->bt.hsync = hsync;
    771	fmt->bt.vsync = vsync;
    772	fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
    773
    774	if (!interlaced) {
    775		fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
    776		fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
    777	} else {
    778		fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
    779				      2 * vsync) / 2;
    780		fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
    781					2 * vsync - fmt->bt.vbackporch;
    782		fmt->bt.il_vfrontporch = v_fp;
    783		fmt->bt.il_vsync = vsync;
    784		fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
    785		fmt->bt.interlaced = V4L2_DV_INTERLACED;
    786	}
    787
    788	fmt->bt.pixelclock = pix_clk;
    789	fmt->bt.standards = V4L2_DV_BT_STD_GTF;
    790
    791	if (!default_gtf)
    792		fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
    793
    794	return true;
    795}
    796EXPORT_SYMBOL_GPL(v4l2_detect_gtf);
    797
    798/** v4l2_calc_aspect_ratio - calculate the aspect ratio based on bytes
    799 *	0x15 and 0x16 from the EDID.
    800 * @hor_landscape - byte 0x15 from the EDID.
    801 * @vert_portrait - byte 0x16 from the EDID.
    802 *
    803 * Determines the aspect ratio from the EDID.
    804 * See VESA Enhanced EDID standard, release A, rev 2, section 3.6.2:
    805 * "Horizontal and Vertical Screen Size or Aspect Ratio"
    806 */
    807struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait)
    808{
    809	struct v4l2_fract aspect = { 16, 9 };
    810	u8 ratio;
    811
    812	/* Nothing filled in, fallback to 16:9 */
    813	if (!hor_landscape && !vert_portrait)
    814		return aspect;
    815	/* Both filled in, so they are interpreted as the screen size in cm */
    816	if (hor_landscape && vert_portrait) {
    817		aspect.numerator = hor_landscape;
    818		aspect.denominator = vert_portrait;
    819		return aspect;
    820	}
    821	/* Only one is filled in, so interpret them as a ratio:
    822	   (val + 99) / 100 */
    823	ratio = hor_landscape | vert_portrait;
    824	/* Change some rounded values into the exact aspect ratio */
    825	if (ratio == 79) {
    826		aspect.numerator = 16;
    827		aspect.denominator = 9;
    828	} else if (ratio == 34) {
    829		aspect.numerator = 4;
    830		aspect.denominator = 3;
    831	} else if (ratio == 68) {
    832		aspect.numerator = 15;
    833		aspect.denominator = 9;
    834	} else {
    835		aspect.numerator = hor_landscape + 99;
    836		aspect.denominator = 100;
    837	}
    838	if (hor_landscape)
    839		return aspect;
    840	/* The aspect ratio is for portrait, so swap numerator and denominator */
    841	swap(aspect.denominator, aspect.numerator);
    842	return aspect;
    843}
    844EXPORT_SYMBOL_GPL(v4l2_calc_aspect_ratio);
    845
    846/** v4l2_hdmi_rx_colorimetry - determine HDMI colorimetry information
    847 *	based on various InfoFrames.
    848 * @avi: the AVI InfoFrame
    849 * @hdmi: the HDMI Vendor InfoFrame, may be NULL
    850 * @height: the frame height
    851 *
    852 * Determines the HDMI colorimetry information, i.e. how the HDMI
    853 * pixel color data should be interpreted.
    854 *
    855 * Note that some of the newer features (DCI-P3, HDR) are not yet
    856 * implemented: the hdmi.h header needs to be updated to the HDMI 2.0
    857 * and CTA-861-G standards.
    858 */
    859struct v4l2_hdmi_colorimetry
    860v4l2_hdmi_rx_colorimetry(const struct hdmi_avi_infoframe *avi,
    861			 const struct hdmi_vendor_infoframe *hdmi,
    862			 unsigned int height)
    863{
    864	struct v4l2_hdmi_colorimetry c = {
    865		V4L2_COLORSPACE_SRGB,
    866		V4L2_YCBCR_ENC_DEFAULT,
    867		V4L2_QUANTIZATION_FULL_RANGE,
    868		V4L2_XFER_FUNC_SRGB
    869	};
    870	bool is_ce = avi->video_code || (hdmi && hdmi->vic);
    871	bool is_sdtv = height <= 576;
    872	bool default_is_lim_range_rgb = avi->video_code > 1;
    873
    874	switch (avi->colorspace) {
    875	case HDMI_COLORSPACE_RGB:
    876		/* RGB pixel encoding */
    877		switch (avi->colorimetry) {
    878		case HDMI_COLORIMETRY_EXTENDED:
    879			switch (avi->extended_colorimetry) {
    880			case HDMI_EXTENDED_COLORIMETRY_OPRGB:
    881				c.colorspace = V4L2_COLORSPACE_OPRGB;
    882				c.xfer_func = V4L2_XFER_FUNC_OPRGB;
    883				break;
    884			case HDMI_EXTENDED_COLORIMETRY_BT2020:
    885				c.colorspace = V4L2_COLORSPACE_BT2020;
    886				c.xfer_func = V4L2_XFER_FUNC_709;
    887				break;
    888			default:
    889				break;
    890			}
    891			break;
    892		default:
    893			break;
    894		}
    895		switch (avi->quantization_range) {
    896		case HDMI_QUANTIZATION_RANGE_LIMITED:
    897			c.quantization = V4L2_QUANTIZATION_LIM_RANGE;
    898			break;
    899		case HDMI_QUANTIZATION_RANGE_FULL:
    900			break;
    901		default:
    902			if (default_is_lim_range_rgb)
    903				c.quantization = V4L2_QUANTIZATION_LIM_RANGE;
    904			break;
    905		}
    906		break;
    907
    908	default:
    909		/* YCbCr pixel encoding */
    910		c.quantization = V4L2_QUANTIZATION_LIM_RANGE;
    911		switch (avi->colorimetry) {
    912		case HDMI_COLORIMETRY_NONE:
    913			if (!is_ce)
    914				break;
    915			if (is_sdtv) {
    916				c.colorspace = V4L2_COLORSPACE_SMPTE170M;
    917				c.ycbcr_enc = V4L2_YCBCR_ENC_601;
    918			} else {
    919				c.colorspace = V4L2_COLORSPACE_REC709;
    920				c.ycbcr_enc = V4L2_YCBCR_ENC_709;
    921			}
    922			c.xfer_func = V4L2_XFER_FUNC_709;
    923			break;
    924		case HDMI_COLORIMETRY_ITU_601:
    925			c.colorspace = V4L2_COLORSPACE_SMPTE170M;
    926			c.ycbcr_enc = V4L2_YCBCR_ENC_601;
    927			c.xfer_func = V4L2_XFER_FUNC_709;
    928			break;
    929		case HDMI_COLORIMETRY_ITU_709:
    930			c.colorspace = V4L2_COLORSPACE_REC709;
    931			c.ycbcr_enc = V4L2_YCBCR_ENC_709;
    932			c.xfer_func = V4L2_XFER_FUNC_709;
    933			break;
    934		case HDMI_COLORIMETRY_EXTENDED:
    935			switch (avi->extended_colorimetry) {
    936			case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601:
    937				c.colorspace = V4L2_COLORSPACE_REC709;
    938				c.ycbcr_enc = V4L2_YCBCR_ENC_XV709;
    939				c.xfer_func = V4L2_XFER_FUNC_709;
    940				break;
    941			case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709:
    942				c.colorspace = V4L2_COLORSPACE_REC709;
    943				c.ycbcr_enc = V4L2_YCBCR_ENC_XV601;
    944				c.xfer_func = V4L2_XFER_FUNC_709;
    945				break;
    946			case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
    947				c.colorspace = V4L2_COLORSPACE_SRGB;
    948				c.ycbcr_enc = V4L2_YCBCR_ENC_601;
    949				c.xfer_func = V4L2_XFER_FUNC_SRGB;
    950				break;
    951			case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
    952				c.colorspace = V4L2_COLORSPACE_OPRGB;
    953				c.ycbcr_enc = V4L2_YCBCR_ENC_601;
    954				c.xfer_func = V4L2_XFER_FUNC_OPRGB;
    955				break;
    956			case HDMI_EXTENDED_COLORIMETRY_BT2020:
    957				c.colorspace = V4L2_COLORSPACE_BT2020;
    958				c.ycbcr_enc = V4L2_YCBCR_ENC_BT2020;
    959				c.xfer_func = V4L2_XFER_FUNC_709;
    960				break;
    961			case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
    962				c.colorspace = V4L2_COLORSPACE_BT2020;
    963				c.ycbcr_enc = V4L2_YCBCR_ENC_BT2020_CONST_LUM;
    964				c.xfer_func = V4L2_XFER_FUNC_709;
    965				break;
    966			default: /* fall back to ITU_709 */
    967				c.colorspace = V4L2_COLORSPACE_REC709;
    968				c.ycbcr_enc = V4L2_YCBCR_ENC_709;
    969				c.xfer_func = V4L2_XFER_FUNC_709;
    970				break;
    971			}
    972			break;
    973		default:
    974			break;
    975		}
    976		/*
    977		 * YCC Quantization Range signaling is more-or-less broken,
    978		 * let's just ignore this.
    979		 */
    980		break;
    981	}
    982	return c;
    983}
    984EXPORT_SYMBOL_GPL(v4l2_hdmi_rx_colorimetry);
    985
    986/**
    987 * v4l2_get_edid_phys_addr() - find and return the physical address
    988 *
    989 * @edid:	pointer to the EDID data
    990 * @size:	size in bytes of the EDID data
    991 * @offset:	If not %NULL then the location of the physical address
    992 *		bytes in the EDID will be returned here. This is set to 0
    993 *		if there is no physical address found.
    994 *
    995 * Return: the physical address or CEC_PHYS_ADDR_INVALID if there is none.
    996 */
    997u16 v4l2_get_edid_phys_addr(const u8 *edid, unsigned int size,
    998			    unsigned int *offset)
    999{
   1000	unsigned int loc = cec_get_edid_spa_location(edid, size);
   1001
   1002	if (offset)
   1003		*offset = loc;
   1004	if (loc == 0)
   1005		return CEC_PHYS_ADDR_INVALID;
   1006	return (edid[loc] << 8) | edid[loc + 1];
   1007}
   1008EXPORT_SYMBOL_GPL(v4l2_get_edid_phys_addr);
   1009
   1010/**
   1011 * v4l2_set_edid_phys_addr() - find and set the physical address
   1012 *
   1013 * @edid:	pointer to the EDID data
   1014 * @size:	size in bytes of the EDID data
   1015 * @phys_addr:	the new physical address
   1016 *
   1017 * This function finds the location of the physical address in the EDID
   1018 * and fills in the given physical address and updates the checksum
   1019 * at the end of the EDID block. It does nothing if the EDID doesn't
   1020 * contain a physical address.
   1021 */
   1022void v4l2_set_edid_phys_addr(u8 *edid, unsigned int size, u16 phys_addr)
   1023{
   1024	unsigned int loc = cec_get_edid_spa_location(edid, size);
   1025	u8 sum = 0;
   1026	unsigned int i;
   1027
   1028	if (loc == 0)
   1029		return;
   1030	edid[loc] = phys_addr >> 8;
   1031	edid[loc + 1] = phys_addr & 0xff;
   1032	loc &= ~0x7f;
   1033
   1034	/* update the checksum */
   1035	for (i = loc; i < loc + 127; i++)
   1036		sum += edid[i];
   1037	edid[i] = 256 - sum;
   1038}
   1039EXPORT_SYMBOL_GPL(v4l2_set_edid_phys_addr);
   1040
   1041/**
   1042 * v4l2_phys_addr_for_input() - calculate the PA for an input
   1043 *
   1044 * @phys_addr:	the physical address of the parent
   1045 * @input:	the number of the input port, must be between 1 and 15
   1046 *
   1047 * This function calculates a new physical address based on the input
   1048 * port number. For example:
   1049 *
   1050 * PA = 0.0.0.0 and input = 2 becomes 2.0.0.0
   1051 *
   1052 * PA = 3.0.0.0 and input = 1 becomes 3.1.0.0
   1053 *
   1054 * PA = 3.2.1.0 and input = 5 becomes 3.2.1.5
   1055 *
   1056 * PA = 3.2.1.3 and input = 5 becomes f.f.f.f since it maxed out the depth.
   1057 *
   1058 * Return: the new physical address or CEC_PHYS_ADDR_INVALID.
   1059 */
   1060u16 v4l2_phys_addr_for_input(u16 phys_addr, u8 input)
   1061{
   1062	/* Check if input is sane */
   1063	if (WARN_ON(input == 0 || input > 0xf))
   1064		return CEC_PHYS_ADDR_INVALID;
   1065
   1066	if (phys_addr == 0)
   1067		return input << 12;
   1068
   1069	if ((phys_addr & 0x0fff) == 0)
   1070		return phys_addr | (input << 8);
   1071
   1072	if ((phys_addr & 0x00ff) == 0)
   1073		return phys_addr | (input << 4);
   1074
   1075	if ((phys_addr & 0x000f) == 0)
   1076		return phys_addr | input;
   1077
   1078	/*
   1079	 * All nibbles are used so no valid physical addresses can be assigned
   1080	 * to the input.
   1081	 */
   1082	return CEC_PHYS_ADDR_INVALID;
   1083}
   1084EXPORT_SYMBOL_GPL(v4l2_phys_addr_for_input);
   1085
   1086/**
   1087 * v4l2_phys_addr_validate() - validate a physical address from an EDID
   1088 *
   1089 * @phys_addr:	the physical address to validate
   1090 * @parent:	if not %NULL, then this is filled with the parents PA.
   1091 * @port:	if not %NULL, then this is filled with the input port.
   1092 *
   1093 * This validates a physical address as read from an EDID. If the
   1094 * PA is invalid (such as 1.0.1.0 since '0' is only allowed at the end),
   1095 * then it will return -EINVAL.
   1096 *
   1097 * The parent PA is passed into %parent and the input port is passed into
   1098 * %port. For example:
   1099 *
   1100 * PA = 0.0.0.0: has parent 0.0.0.0 and input port 0.
   1101 *
   1102 * PA = 1.0.0.0: has parent 0.0.0.0 and input port 1.
   1103 *
   1104 * PA = 3.2.0.0: has parent 3.0.0.0 and input port 2.
   1105 *
   1106 * PA = f.f.f.f: has parent f.f.f.f and input port 0.
   1107 *
   1108 * Return: 0 if the PA is valid, -EINVAL if not.
   1109 */
   1110int v4l2_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port)
   1111{
   1112	int i;
   1113
   1114	if (parent)
   1115		*parent = phys_addr;
   1116	if (port)
   1117		*port = 0;
   1118	if (phys_addr == CEC_PHYS_ADDR_INVALID)
   1119		return 0;
   1120	for (i = 0; i < 16; i += 4)
   1121		if (phys_addr & (0xf << i))
   1122			break;
   1123	if (i == 16)
   1124		return 0;
   1125	if (parent)
   1126		*parent = phys_addr & (0xfff0 << i);
   1127	if (port)
   1128		*port = (phys_addr >> i) & 0xf;
   1129	for (i += 4; i < 16; i += 4)
   1130		if ((phys_addr & (0xf << i)) == 0)
   1131			return -EINVAL;
   1132	return 0;
   1133}
   1134EXPORT_SYMBOL_GPL(v4l2_phys_addr_validate);