linux/drivers/gpu/drm/drm_edid.c

/*
 * Copyright (c) 2006 Luc Verhaegen (quirks list)
 * Copyright (c) 2007-2008 Intel Corporation
 *   Jesse Barnes <[email protected]>
 * Copyright 2010 Red Hat, Inc.
 *
 * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from
 * FB layer.
 *   Copyright (C) 2006 Dennis Munsie <[email protected]>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#include <linux/bitfield.h>
#include <linux/byteorder/generic.h>
#include <linux/cec.h>
#include <linux/hdmi.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/seq_buf.h>
#include <linux/slab.h>
#include <linux/vga_switcheroo.h>

#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
#include <drm/drm_encoder.h>
#include <drm/drm_print.h>

#include "drm_crtc_internal.h"
#include "drm_displayid_internal.h"
#include "drm_internal.h"

static int oui(u8 first, u8 second, u8 third)
{}

#define EDID_EST_TIMINGS
#define EDID_STD_TIMINGS
#define EDID_DETAILED_TIMINGS

/*
 * EDID blocks out in the wild have a variety of bugs, try to collect
 * them here (note that userspace may work around broken monitors first,
 * but fixes should make their way here so that the kernel "just works"
 * on as many displays as possible).
 */

/* First detailed mode wrong, use largest 60Hz mode */
#define EDID_QUIRK_PREFER_LARGE_60
/* Reported 135MHz pixel clock is too high, needs adjustment */
#define EDID_QUIRK_135_CLOCK_TOO_HIGH
/* Prefer the largest mode at 75 Hz */
#define EDID_QUIRK_PREFER_LARGE_75
/* Detail timing is in cm not mm */
#define EDID_QUIRK_DETAILED_IN_CM
/* Detailed timing descriptors have bogus size values, so just take the
 * maximum size and use that.
 */
#define EDID_QUIRK_DETAILED_USE_MAXIMUM_SIZE
/* use +hsync +vsync for detailed mode */
#define EDID_QUIRK_DETAILED_SYNC_PP
/* Force reduced-blanking timings for detailed modes */
#define EDID_QUIRK_FORCE_REDUCED_BLANKING
/* Force 8bpc */
#define EDID_QUIRK_FORCE_8BPC
/* Force 12bpc */
#define EDID_QUIRK_FORCE_12BPC
/* Force 6bpc */
#define EDID_QUIRK_FORCE_6BPC
/* Force 10bpc */
#define EDID_QUIRK_FORCE_10BPC
/* Non desktop display (i.e. HMD) */
#define EDID_QUIRK_NON_DESKTOP
/* Cap the DSC target bitrate to 15bpp */
#define EDID_QUIRK_CAP_DSC_15BPP

#define MICROSOFT_IEEE_OUI

struct detailed_mode_closure {};

struct drm_edid_match_closure {};

#define LEVEL_DMT
#define LEVEL_GTF
#define LEVEL_GTF2
#define LEVEL_CVT

#define EDID_QUIRK(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _quirks)

static const struct edid_quirk {} edid_quirk_list[] =;

/*
 * Autogenerated from the DMT spec.
 * This table is copied from xfree86/modes/xf86EdidModes.c.
 */
static const struct drm_display_mode drm_dmt_modes[] =;

/*
 * These more or less come from the DMT spec.  The 720x400 modes are
 * inferred from historical 80x25 practice.  The 640x480@67 and 832x624@75
 * modes are old-school Mac modes.  The EDID spec says the 1152x864@75 mode
 * should be 1152x870, again for the Mac, but instead we use the x864 DMT
 * mode.
 *
 * The DMT modes have been fact-checked; the rest are mild guesses.
 */
static const struct drm_display_mode edid_est_modes[] =;

struct minimode {};

static const struct minimode est3_modes[] =;

static const struct minimode extra_modes[] =;

/*
 * From CEA/CTA-861 spec.
 *
 * Do not access directly, instead always use cea_mode_for_vic().
 */
static const struct drm_display_mode edid_cea_modes_1[] =;

/*
 * From CEA/CTA-861 spec.
 *
 * Do not access directly, instead always use cea_mode_for_vic().
 */
static const struct drm_display_mode edid_cea_modes_193[] =;

/*
 * HDMI 1.4 4k modes. Index using the VIC.
 */
static const struct drm_display_mode edid_4k_modes[] =;

/*** DDC fetch and block validation ***/

/*
 * The opaque EDID type, internal to drm_edid.c.
 */
struct drm_edid {};

static int edid_hfeeodb_extension_block_count(const struct edid *edid);

static int edid_hfeeodb_block_count(const struct edid *edid)
{}

static int edid_extension_block_count(const struct edid *edid)
{}

static int edid_block_count(const struct edid *edid)
{}

static int edid_size_by_blocks(int num_blocks)
{}

static int edid_size(const struct edid *edid)
{}

static const void *edid_block_data(const struct edid *edid, int index)
{}

static const void *edid_extension_block_data(const struct edid *edid, int index)
{}

/* EDID block count indicated in EDID, may exceed allocated size */
static int __drm_edid_block_count(const struct drm_edid *drm_edid)
{}

/* EDID block count, limited by allocated size */
static int drm_edid_block_count(const struct drm_edid *drm_edid)
{}

/* EDID extension block count, limited by allocated size */
static int drm_edid_extension_block_count(const struct drm_edid *drm_edid)
{}

static const void *drm_edid_block_data(const struct drm_edid *drm_edid, int index)
{}

static const void *drm_edid_extension_block_data(const struct drm_edid *drm_edid,
						 int index)
{}

/*
 * Initializer helper for legacy interfaces, where we have no choice but to
 * trust edid size. Not for general purpose use.
 */
static const struct drm_edid *drm_edid_legacy_init(struct drm_edid *drm_edid,
						   const struct edid *edid)
{}

/*
 * EDID base and extension block iterator.
 *
 * struct drm_edid_iter iter;
 * const u8 *block;
 *
 * drm_edid_iter_begin(drm_edid, &iter);
 * drm_edid_iter_for_each(block, &iter) {
 *         // do stuff with block
 * }
 * drm_edid_iter_end(&iter);
 */
struct drm_edid_iter {};

static void drm_edid_iter_begin(const struct drm_edid *drm_edid,
				struct drm_edid_iter *iter)
{}

static const void *__drm_edid_iter_next(struct drm_edid_iter *iter)
{}

#define drm_edid_iter_for_each(__block, __iter)

static void drm_edid_iter_end(struct drm_edid_iter *iter)
{}

static const u8 edid_header[] =;

static void edid_header_fix(void *edid)
{}

/**
 * drm_edid_header_is_valid - sanity check the header of the base EDID block
 * @_edid: pointer to raw base EDID block
 *
 * Sanity check the header of the base EDID block.
 *
 * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
 */
int drm_edid_header_is_valid(const void *_edid)
{}
EXPORT_SYMBOL();

static int edid_fixup __read_mostly =;
module_param_named(edid_fixup, edid_fixup, int, 0400);
MODULE_PARM_DESC();

static int edid_block_compute_checksum(const void *_block)
{}

static int edid_block_get_checksum(const void *_block)
{}

static int edid_block_tag(const void *_block)
{}

static bool edid_block_is_zero(const void *edid)
{}

static bool drm_edid_eq(const struct drm_edid *drm_edid,
			const void *raw_edid, size_t raw_edid_size)
{}

enum edid_block_status {};

static enum edid_block_status edid_block_check(const void *_block,
					       bool is_base_block)
{}

static bool edid_block_status_valid(enum edid_block_status status, int tag)
{}

static bool edid_block_valid(const void *block, bool base)
{}

static void edid_block_status_print(enum edid_block_status status,
				    const struct edid *block,
				    int block_num)
{}

static void edid_block_dump(const char *level, const void *block, int block_num)
{}

/*
 * Validate a base or extension EDID block and optionally dump bad blocks to
 * the console.
 */
static bool drm_edid_block_valid(void *_block, int block_num, bool print_bad_edid,
				 bool *edid_corrupt)
{}

/**
 * drm_edid_is_valid - sanity check EDID data
 * @edid: EDID data
 *
 * Sanity-check an entire EDID record (including extensions)
 *
 * Return: True if the EDID data is valid, false otherwise.
 */
bool drm_edid_is_valid(struct edid *edid)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_valid - sanity check EDID data
 * @drm_edid: EDID data
 *
 * Sanity check an EDID. Cross check block count against allocated size and
 * checksum the blocks.
 *
 * Return: True if the EDID data is valid, false otherwise.
 */
bool drm_edid_valid(const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();

static struct edid *edid_filter_invalid_blocks(struct edid *edid,
					       size_t *alloc_size)
{}

#define DDC_SEGMENT_ADDR
/**
 * drm_do_probe_ddc_edid() - get EDID information via I2C
 * @data: I2C device adapter
 * @buf: EDID data buffer to be filled
 * @block: 128 byte EDID block to start fetching from
 * @len: EDID data buffer length to fetch
 *
 * Try to fetch EDID information by calling I2C driver functions.
 *
 * Return: 0 on success or -1 on failure.
 */
static int
drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
{}

static void connector_bad_edid(struct drm_connector *connector,
			       const struct edid *edid, int num_blocks)
{}

/* Get override or firmware EDID */
static const struct drm_edid *drm_edid_override_get(struct drm_connector *connector)
{}

/* For debugfs edid_override implementation */
int drm_edid_override_show(struct drm_connector *connector, struct seq_file *m)
{}

/* For debugfs edid_override implementation */
int drm_edid_override_set(struct drm_connector *connector, const void *edid,
			  size_t size)
{}

/* For debugfs edid_override implementation */
int drm_edid_override_reset(struct drm_connector *connector)
{}

/**
 * drm_edid_override_connector_update - add modes from override/firmware EDID
 * @connector: connector we're probing
 *
 * Add modes from the override/firmware EDID, if available. Only to be used from
 * drm_helper_probe_single_connector_modes() as a fallback for when DDC probe
 * failed during drm_get_edid() and caused the override/firmware EDID to be
 * skipped.
 *
 * Return: The number of modes added or 0 if we couldn't find any.
 */
int drm_edid_override_connector_update(struct drm_connector *connector)
{}
EXPORT_SYMBOL();

read_block_fn;

static enum edid_block_status edid_block_read(void *block, unsigned int block_num,
					      read_block_fn read_block,
					      void *context)
{}

static struct edid *_drm_do_get_edid(struct drm_connector *connector,
				     read_block_fn read_block, void *context,
				     size_t *size)
{}

/**
 * drm_edid_raw - Get a pointer to the raw EDID data.
 * @drm_edid: drm_edid container
 *
 * Get a pointer to the raw EDID data.
 *
 * This is for transition only. Avoid using this like the plague.
 *
 * Return: Pointer to raw EDID data.
 */
const struct edid *drm_edid_raw(const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();

/* Allocate struct drm_edid container *without* duplicating the edid data */
static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size)
{}

/**
 * drm_edid_alloc - Allocate a new drm_edid container
 * @edid: Pointer to raw EDID data
 * @size: Size of memory allocated for EDID
 *
 * Allocate a new drm_edid container. Do not calculate edid size from edid, pass
 * the actual size that has been allocated for the data. There is no validation
 * of the raw EDID data against the size, but at least the EDID base block must
 * fit in the buffer.
 *
 * The returned pointer must be freed using drm_edid_free().
 *
 * Return: drm_edid container, or NULL on errors
 */
const struct drm_edid *drm_edid_alloc(const void *edid, size_t size)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_dup - Duplicate a drm_edid container
 * @drm_edid: EDID to duplicate
 *
 * The returned pointer must be freed using drm_edid_free().
 *
 * Returns: drm_edid container copy, or NULL on errors
 */
const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_free - Free the drm_edid container
 * @drm_edid: EDID to free
 */
void drm_edid_free(const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();

/**
 * drm_probe_ddc() - probe DDC presence
 * @adapter: I2C adapter to probe
 *
 * Return: True on success, false on failure.
 */
bool
drm_probe_ddc(struct i2c_adapter *adapter)
{}
EXPORT_SYMBOL();

/**
 * drm_get_edid - get EDID data, if available
 * @connector: connector we're probing
 * @adapter: I2C adapter to use for DDC
 *
 * Poke the given I2C channel to grab EDID data if possible.  If found,
 * attach it to the connector.
 *
 * Return: Pointer to valid EDID or NULL if we couldn't find any.
 */
struct edid *drm_get_edid(struct drm_connector *connector,
			  struct i2c_adapter *adapter)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_read_custom - Read EDID data using given EDID block read function
 * @connector: Connector to use
 * @read_block: EDID block read function
 * @context: Private data passed to the block read function
 *
 * When the I2C adapter connected to the DDC bus is hidden behind a device that
 * exposes a different interface to read EDID blocks this function can be used
 * to get EDID data using a custom block read function.
 *
 * As in the general case the DDC bus is accessible by the kernel at the I2C
 * level, drivers must make all reasonable efforts to expose it as an I2C
 * adapter and use drm_edid_read() or drm_edid_read_ddc() instead of abusing
 * this function.
 *
 * The EDID may be overridden using debugfs override_edid or firmware EDID
 * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority
 * order. Having either of them bypasses actual EDID reads.
 *
 * The returned pointer must be freed using drm_edid_free().
 *
 * Return: Pointer to EDID, or NULL if probe/read failed.
 */
const struct drm_edid *drm_edid_read_custom(struct drm_connector *connector,
					    read_block_fn read_block,
					    void *context)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_read_ddc - Read EDID data using given I2C adapter
 * @connector: Connector to use
 * @adapter: I2C adapter to use for DDC
 *
 * Read EDID using the given I2C adapter.
 *
 * The EDID may be overridden using debugfs override_edid or firmware EDID
 * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority
 * order. Having either of them bypasses actual EDID reads.
 *
 * Prefer initializing connector->ddc with drm_connector_init_with_ddc() and
 * using drm_edid_read() instead of this function.
 *
 * The returned pointer must be freed using drm_edid_free().
 *
 * Return: Pointer to EDID, or NULL if probe/read failed.
 */
const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,
					 struct i2c_adapter *adapter)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_read - Read EDID data using connector's I2C adapter
 * @connector: Connector to use
 *
 * Read EDID using the connector's I2C adapter.
 *
 * The EDID may be overridden using debugfs override_edid or firmware EDID
 * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority
 * order. Having either of them bypasses actual EDID reads.
 *
 * The returned pointer must be freed using drm_edid_free().
 *
 * Return: Pointer to EDID, or NULL if probe/read failed.
 */
const struct drm_edid *drm_edid_read(struct drm_connector *connector)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_get_product_id - Get the vendor and product identification
 * @drm_edid: EDID
 * @id: Where to place the product id
 */
void drm_edid_get_product_id(const struct drm_edid *drm_edid,
			     struct drm_edid_product_id *id)
{}
EXPORT_SYMBOL();

static void decode_date(struct seq_buf *s, const struct drm_edid_product_id *id)
{}

/**
 * drm_edid_print_product_id - Print decoded product id to printer
 * @p: drm printer
 * @id: EDID product id
 * @raw: If true, also print the raw hex
 *
 * See VESA E-EDID 1.4 section 3.4.
 */
void drm_edid_print_product_id(struct drm_printer *p,
			       const struct drm_edid_product_id *id, bool raw)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_get_panel_id - Get a panel's ID from EDID
 * @drm_edid: EDID that contains panel ID.
 *
 * This function uses the first block of the EDID of a panel and (assuming
 * that the EDID is valid) extracts the ID out of it. The ID is a 32-bit value
 * (16 bits of manufacturer ID and 16 bits of per-manufacturer ID) that's
 * supposed to be different for each different modem of panel.
 *
 * Return: A 32-bit ID that should be different for each make/model of panel.
 *         See the functions drm_edid_encode_panel_id() and
 *         drm_edid_decode_panel_id() for some details on the structure of this
 *         ID. Return 0 if the EDID size is less than a base block.
 */
u32 drm_edid_get_panel_id(const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_read_base_block - Get a panel's EDID base block
 * @adapter: I2C adapter to use for DDC
 *
 * This function returns the drm_edid containing the first block of the EDID of
 * a panel.
 *
 * This function is intended to be used during early probing on devices where
 * more than one panel might be present. Because of its intended use it must
 * assume that the EDID of the panel is correct, at least as far as the base
 * block is concerned (in other words, we don't process any overrides here).
 *
 * Caller should call drm_edid_free() after use.
 *
 * NOTE: it's expected that this function and drm_do_get_edid() will both
 * be read the EDID, but there is no caching between them. Since we're only
 * reading the first block, hopefully this extra overhead won't be too big.
 *
 * WARNING: Only use this function when the connector is unknown. For example,
 * during the early probe of panel. The EDID read from the function is temporary
 * and should be replaced by the full EDID returned from other drm_edid_read.
 *
 * Return: Pointer to allocated EDID base block, or NULL on any failure.
 */
const struct drm_edid *drm_edid_read_base_block(struct i2c_adapter *adapter)
{}
EXPORT_SYMBOL();

/**
 * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
 * @connector: connector we're probing
 * @adapter: I2C adapter to use for DDC
 *
 * Wrapper around drm_get_edid() for laptops with dual GPUs using one set of
 * outputs. The wrapper adds the requisite vga_switcheroo calls to temporarily
 * switch DDC to the GPU which is retrieving EDID.
 *
 * Return: Pointer to valid EDID or %NULL if we couldn't find any.
 */
struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
				     struct i2c_adapter *adapter)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_read_switcheroo - get EDID data for a vga_switcheroo output
 * @connector: connector we're probing
 * @adapter: I2C adapter to use for DDC
 *
 * Wrapper around drm_edid_read_ddc() for laptops with dual GPUs using one set
 * of outputs. The wrapper adds the requisite vga_switcheroo calls to
 * temporarily switch DDC to the GPU which is retrieving EDID.
 *
 * Return: Pointer to valid EDID or %NULL if we couldn't find any.
 */
const struct drm_edid *drm_edid_read_switcheroo(struct drm_connector *connector,
						struct i2c_adapter *adapter)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_duplicate - duplicate an EDID and the extensions
 * @edid: EDID to duplicate
 *
 * Return: Pointer to duplicated EDID or NULL on allocation failure.
 */
struct edid *drm_edid_duplicate(const struct edid *edid)
{}
EXPORT_SYMBOL();

/*** EDID parsing ***/

/**
 * edid_get_quirks - return quirk flags for a given EDID
 * @drm_edid: EDID to process
 *
 * This tells subsequent routines what fixes they need to apply.
 *
 * Return: A u32 represents the quirks to apply.
 */
static u32 edid_get_quirks(const struct drm_edid *drm_edid)
{}

#define MODE_SIZE(m)
#define MODE_REFRESH_DIFF(c,t)

/*
 * Walk the mode list for connector, clearing the preferred status on existing
 * modes and setting it anew for the right mode ala quirks.
 */
static void edid_fixup_preferred(struct drm_connector *connector)
{}

static bool
mode_is_rb(const struct drm_display_mode *mode)
{}

/*
 * drm_mode_find_dmt - Create a copy of a mode if present in DMT
 * @dev: Device to duplicate against
 * @hsize: Mode width
 * @vsize: Mode height
 * @fresh: Mode refresh rate
 * @rb: Mode reduced-blanking-ness
 *
 * Walk the DMT mode list looking for a match for the given parameters.
 *
 * Return: A newly allocated copy of the mode, or NULL if not found.
 */
struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev,
					   int hsize, int vsize, int fresh,
					   bool rb)
{}
EXPORT_SYMBOL();

static bool is_display_descriptor(const struct detailed_timing *descriptor, u8 type)
{}

static bool is_detailed_timing_descriptor(const struct detailed_timing *descriptor)
{}

detailed_cb;

static void
cea_for_each_detailed_block(const u8 *ext, detailed_cb *cb, void *closure)
{}

static void
vtb_for_each_detailed_block(const u8 *ext, detailed_cb *cb, void *closure)
{}

static void drm_for_each_detailed_block(const struct drm_edid *drm_edid,
					detailed_cb *cb, void *closure)
{}

static void
is_rb(const struct detailed_timing *descriptor, void *data)
{}

/* EDID 1.4 defines this explicitly.  For EDID 1.3, we guess, badly. */
static bool
drm_monitor_supports_rb(const struct drm_edid *drm_edid)
{}

static void
find_gtf2(const struct detailed_timing *descriptor, void *data)
{}

/* Secondary GTF curve kicks in above some break frequency */
static int
drm_gtf2_hbreak(const struct drm_edid *drm_edid)
{}

static int
drm_gtf2_2c(const struct drm_edid *drm_edid)
{}

static int
drm_gtf2_m(const struct drm_edid *drm_edid)
{}

static int
drm_gtf2_k(const struct drm_edid *drm_edid)
{}

static int
drm_gtf2_2j(const struct drm_edid *drm_edid)
{}

static void
get_timing_level(const struct detailed_timing *descriptor, void *data)
{}

/* Get standard timing level (CVT/GTF/DMT). */
static int standard_timing_level(const struct drm_edid *drm_edid)
{}

/*
 * 0 is reserved.  The spec says 0x01 fill for unused timings.  Some old
 * monitors fill with ascii space (0x20) instead.
 */
static int
bad_std_timing(u8 a, u8 b)
{}

static int drm_mode_hsync(const struct drm_display_mode *mode)
{}

static struct drm_display_mode *
drm_gtf2_mode(struct drm_device *dev,
	      const struct drm_edid *drm_edid,
	      int hsize, int vsize, int vrefresh_rate)
{}

/*
 * Take the standard timing params (in this case width, aspect, and refresh)
 * and convert them into a real mode using CVT/GTF/DMT.
 */
static struct drm_display_mode *drm_mode_std(struct drm_connector *connector,
					     const struct drm_edid *drm_edid,
					     const struct std_timing *t)
{}

/*
 * EDID is delightfully ambiguous about how interlaced modes are to be
 * encoded.  Our internal representation is of frame height, but some
 * HDTV detailed timings are encoded as field height.
 *
 * The format list here is from CEA, in frame size.  Technically we
 * should be checking refresh rate too.  Whatever.
 */
static void
drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
			    const struct detailed_pixel_timing *pt)
{}

/*
 * Create a new mode from an EDID detailed timing section. An EDID detailed
 * timing block contains enough info for us to create and return a new struct
 * drm_display_mode.
 */
static struct drm_display_mode *drm_mode_detailed(struct drm_connector *connector,
						  const struct drm_edid *drm_edid,
						  const struct detailed_timing *timing)
{}

static bool
mode_in_hsync_range(const struct drm_display_mode *mode,
		    const struct edid *edid, const u8 *t)
{}

static bool
mode_in_vsync_range(const struct drm_display_mode *mode,
		    const struct edid *edid, const u8 *t)
{}

static u32
range_pixel_clock(const struct edid *edid, const u8 *t)
{}

static bool mode_in_range(const struct drm_display_mode *mode,
			  const struct drm_edid *drm_edid,
			  const struct detailed_timing *timing)
{}

static bool valid_inferred_mode(const struct drm_connector *connector,
				const struct drm_display_mode *mode)
{}

static int drm_dmt_modes_for_range(struct drm_connector *connector,
				   const struct drm_edid *drm_edid,
				   const struct detailed_timing *timing)
{}

/* fix up 1366x768 mode from 1368x768;
 * GFT/CVT can't express 1366 width which isn't dividable by 8
 */
void drm_mode_fixup_1366x768(struct drm_display_mode *mode)
{}

static int drm_gtf_modes_for_range(struct drm_connector *connector,
				   const struct drm_edid *drm_edid,
				   const struct detailed_timing *timing)
{}

static int drm_gtf2_modes_for_range(struct drm_connector *connector,
				    const struct drm_edid *drm_edid,
				    const struct detailed_timing *timing)
{}

static int drm_cvt_modes_for_range(struct drm_connector *connector,
				   const struct drm_edid *drm_edid,
				   const struct detailed_timing *timing)
{}

static void
do_inferred_modes(const struct detailed_timing *timing, void *c)
{}

static int add_inferred_modes(struct drm_connector *connector,
			      const struct drm_edid *drm_edid)
{}

static int
drm_est3_modes(struct drm_connector *connector, const struct detailed_timing *timing)
{}

static void
do_established_modes(const struct detailed_timing *timing, void *c)
{}

/*
 * Get established modes from EDID and add them. Each EDID block contains a
 * bitmap of the supported "established modes" list (defined above). Tease them
 * out and add them to the global modes list.
 */
static int add_established_modes(struct drm_connector *connector,
				 const struct drm_edid *drm_edid)
{}

static void
do_standard_modes(const struct detailed_timing *timing, void *c)
{}

/*
 * Get standard modes from EDID and add them. Standard modes can be calculated
 * using the appropriate standard (DMT, GTF, or CVT). Grab them from EDID and
 * add them to the list.
 */
static int add_standard_modes(struct drm_connector *connector,
			      const struct drm_edid *drm_edid)
{}

static int drm_cvt_modes(struct drm_connector *connector,
			 const struct detailed_timing *timing)
{}

static void
do_cvt_mode(const struct detailed_timing *timing, void *c)
{}

static int
add_cvt_modes(struct drm_connector *connector, const struct drm_edid *drm_edid)
{}

static void fixup_detailed_cea_mode_clock(struct drm_connector *connector,
					  struct drm_display_mode *mode);

static void
do_detailed_mode(const struct detailed_timing *timing, void *c)
{}

/*
 * add_detailed_modes - Add modes from detailed timings
 * @connector: attached connector
 * @drm_edid: EDID block to scan
 */
static int add_detailed_modes(struct drm_connector *connector,
			      const struct drm_edid *drm_edid)
{}

/* CTA-861-H Table 60 - CTA Tag Codes */
#define CTA_DB_AUDIO
#define CTA_DB_VIDEO
#define CTA_DB_VENDOR
#define CTA_DB_SPEAKER
#define CTA_DB_EXTENDED_TAG

/* CTA-861-H Table 62 - CTA Extended Tag Codes */
#define CTA_EXT_DB_VIDEO_CAP
#define CTA_EXT_DB_VENDOR
#define CTA_EXT_DB_HDR_STATIC_METADATA
#define CTA_EXT_DB_420_VIDEO_DATA
#define CTA_EXT_DB_420_VIDEO_CAP_MAP
#define CTA_EXT_DB_HF_EEODB
#define CTA_EXT_DB_HF_SCDB

#define EDID_BASIC_AUDIO
#define EDID_CEA_YCRCB444
#define EDID_CEA_YCRCB422
#define EDID_CEA_VCDB_QS

/*
 * Search EDID for CEA extension block.
 *
 * FIXME: Prefer not returning pointers to raw EDID data.
 */
const u8 *drm_edid_find_extension(const struct drm_edid *drm_edid,
				  int ext_id, int *ext_index)
{}

/* Return true if the EDID has a CTA extension or a DisplayID CTA data block */
static bool drm_edid_has_cta_extension(const struct drm_edid *drm_edid)
{}

static __always_inline const struct drm_display_mode *cea_mode_for_vic(u8 vic)
{}

static u8 cea_num_vics(void)
{}

static u8 cea_next_vic(u8 vic)
{}

/*
 * Calculate the alternate clock for the CEA mode
 * (60Hz vs. 59.94Hz etc.)
 */
static unsigned int
cea_mode_alternate_clock(const struct drm_display_mode *cea_mode)
{}

static bool
cea_mode_alternate_timings(u8 vic, struct drm_display_mode *mode)
{}

static u8 drm_match_cea_mode_clock_tolerance(const struct drm_display_mode *to_match,
					     unsigned int clock_tolerance)
{}

/**
 * drm_match_cea_mode - look for a CEA mode matching given mode
 * @to_match: display mode
 *
 * Return: The CEA Video ID (VIC) of the mode or 0 if it isn't a CEA-861
 * mode.
 */
u8 drm_match_cea_mode(const struct drm_display_mode *to_match)
{}
EXPORT_SYMBOL();

static bool drm_valid_cea_vic(u8 vic)
{}

static enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code)
{}

static enum hdmi_picture_aspect drm_get_hdmi_aspect_ratio(const u8 video_code)
{}

/*
 * Calculate the alternate clock for HDMI modes (those from the HDMI vendor
 * specific block).
 */
static unsigned int
hdmi_mode_alternate_clock(const struct drm_display_mode *hdmi_mode)
{}

static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_match,
					      unsigned int clock_tolerance)
{}

/*
 * drm_match_hdmi_mode - look for a HDMI mode matching given mode
 * @to_match: display mode
 *
 * An HDMI mode is one defined in the HDMI vendor specific block.
 *
 * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one.
 */
static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match)
{}

static bool drm_valid_hdmi_vic(u8 vic)
{}

static int add_alternate_cea_modes(struct drm_connector *connector,
				   const struct drm_edid *drm_edid)
{}

static u8 svd_to_vic(u8 svd)
{}

/*
 * Return a display mode for the 0-based vic_index'th VIC across all CTA VDBs in
 * the EDID, or NULL on errors.
 */
static struct drm_display_mode *
drm_display_mode_from_vic_index(struct drm_connector *connector, int vic_index)
{}

/*
 * do_y420vdb_modes - Parse YCBCR 420 only modes
 * @connector: connector corresponding to the HDMI sink
 * @svds: start of the data block of CEA YCBCR 420 VDB
 * @len: length of the CEA YCBCR 420 VDB
 *
 * Parse the CEA-861-F YCBCR 420 Video Data Block (Y420VDB)
 * which contains modes which can be supported in YCBCR 420
 * output format only.
 */
static int do_y420vdb_modes(struct drm_connector *connector,
			    const u8 *svds, u8 svds_len)
{}

/**
 * drm_display_mode_from_cea_vic() - return a mode for CEA VIC
 * @dev: DRM device
 * @video_code: CEA VIC of the mode
 *
 * Creates a new mode matching the specified CEA VIC.
 *
 * Returns: A new drm_display_mode on success or NULL on failure
 */
struct drm_display_mode *
drm_display_mode_from_cea_vic(struct drm_device *dev,
			      u8 video_code)
{}
EXPORT_SYMBOL();

/* Add modes based on VICs parsed in parse_cta_vdb() */
static int add_cta_vdb_modes(struct drm_connector *connector)
{}

struct stereo_mandatory_mode {};

static const struct stereo_mandatory_mode stereo_mandatory_modes[] =;

static bool
stereo_match_mandatory(const struct drm_display_mode *mode,
		       const struct stereo_mandatory_mode *stereo_mode)
{}

static int add_hdmi_mandatory_stereo_modes(struct drm_connector *connector)
{}

static int add_hdmi_mode(struct drm_connector *connector, u8 vic)
{}

static int add_3d_struct_modes(struct drm_connector *connector, u16 structure,
			       int vic_index)
{}

static bool hdmi_vsdb_latency_present(const u8 *db)
{}

static bool hdmi_vsdb_i_latency_present(const u8 *db)
{}

static int hdmi_vsdb_latency_length(const u8 *db)
{}

/*
 * do_hdmi_vsdb_modes - Parse the HDMI Vendor Specific data block
 * @connector: connector corresponding to the HDMI sink
 * @db: start of the CEA vendor specific block
 * @len: length of the CEA block payload, ie. one can access up to db[len]
 *
 * Parses the HDMI VSDB looking for modes to add to @connector. This function
 * also adds the stereo 3d modes when applicable.
 */
static int
do_hdmi_vsdb_modes(struct drm_connector *connector, const u8 *db, u8 len)
{}

static int
cea_revision(const u8 *cea)
{}

/*
 * CTA Data Block iterator.
 *
 * Iterate through all CTA Data Blocks in both EDID CTA Extensions and DisplayID
 * CTA Data Blocks.
 *
 * struct cea_db *db:
 * struct cea_db_iter iter;
 *
 * cea_db_iter_edid_begin(edid, &iter);
 * cea_db_iter_for_each(db, &iter) {
 *         // do stuff with db
 * }
 * cea_db_iter_end(&iter);
 */
struct cea_db_iter {};

/* CTA-861-H section 7.4 CTA Data BLock Collection */
struct cea_db {} __packed;

static int cea_db_tag(const struct cea_db *db)
{}

static int cea_db_payload_len(const void *_db)
{}

static const void *cea_db_data(const struct cea_db *db)
{}

static bool cea_db_is_extended_tag(const struct cea_db *db, int tag)
{}

static bool cea_db_is_vendor(const struct cea_db *db, int vendor_oui)
{}

static void cea_db_iter_edid_begin(const struct drm_edid *drm_edid,
				   struct cea_db_iter *iter)
{}

static const struct cea_db *
__cea_db_iter_current_block(const struct cea_db_iter *iter)
{}

/*
 * References:
 * - CTA-861-H section 7.3.3 CTA Extension Version 3
 */
static int cea_db_collection_size(const u8 *cta)
{}

/*
 * References:
 * - VESA E-EDID v1.4
 * - CTA-861-H section 7.3.3 CTA Extension Version 3
 */
static const void *__cea_db_iter_edid_next(struct cea_db_iter *iter)
{}

/*
 * References:
 * - DisplayID v1.3 Appendix C: CEA Data Block within a DisplayID Data Block
 * - DisplayID v2.0 section 4.10 CTA DisplayID Data Block
 *
 * Note that the above do not specify any connection between DisplayID Data
 * Block revision and CTA Extension versions.
 */
static const void *__cea_db_iter_displayid_next(struct cea_db_iter *iter)
{}

static const struct cea_db *__cea_db_iter_next(struct cea_db_iter *iter)
{}

#define cea_db_iter_for_each(__db, __iter)

static void cea_db_iter_end(struct cea_db_iter *iter)
{}

static bool cea_db_is_hdmi_vsdb(const struct cea_db *db)
{}

static bool cea_db_is_hdmi_forum_vsdb(const struct cea_db *db)
{}

static bool cea_db_is_hdmi_forum_eeodb(const void *db)
{}

static bool cea_db_is_microsoft_vsdb(const struct cea_db *db)
{}

static bool cea_db_is_vcdb(const struct cea_db *db)
{}

static bool cea_db_is_hdmi_forum_scdb(const struct cea_db *db)
{}

static bool cea_db_is_y420cmdb(const struct cea_db *db)
{}

static bool cea_db_is_y420vdb(const struct cea_db *db)
{}

static bool cea_db_is_hdmi_hdr_metadata_block(const struct cea_db *db)
{}

/*
 * Get the HF-EEODB override extension block count from EDID.
 *
 * The passed in EDID may be partially read, as long as it has at least two
 * blocks (base block and one extension block) if EDID extension count is > 0.
 *
 * Note that this is *not* how you should parse CTA Data Blocks in general; this
 * is only to handle partially read EDIDs. Normally, use the CTA Data Block
 * iterators instead.
 *
 * References:
 * - HDMI 2.1 section 10.3.6 HDMI Forum EDID Extension Override Data Block
 */
static int edid_hfeeodb_extension_block_count(const struct edid *edid)
{}

/*
 * CTA-861 YCbCr 4:2:0 Capability Map Data Block (CTA Y420CMDB)
 *
 * Y420CMDB contains a bitmap which gives the index of CTA modes from CTA VDB,
 * which can support YCBCR 420 sampling output also (apart from RGB/YCBCR444
 * etc). For example, if the bit 0 in bitmap is set, first mode in VDB can
 * support YCBCR420 output too.
 */
static void parse_cta_y420cmdb(struct drm_connector *connector,
			       const struct cea_db *db, u64 *y420cmdb_map)
{}

static int add_cea_modes(struct drm_connector *connector,
			 const struct drm_edid *drm_edid)
{}

static void fixup_detailed_cea_mode_clock(struct drm_connector *connector,
					  struct drm_display_mode *mode)
{}

static void drm_calculate_luminance_range(struct drm_connector *connector)
{}

static uint8_t eotf_supported(const u8 *edid_ext)
{}

static uint8_t hdr_metadata_type(const u8 *edid_ext)
{}

static void
drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
{}

/* HDMI Vendor-Specific Data Block (HDMI VSDB, H14b-VSDB) */
static void
drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
{}

static void
match_identity(const struct detailed_timing *timing, void *data)
{}

/**
 * drm_edid_match - match drm_edid with given identity
 * @drm_edid: EDID
 * @ident: the EDID identity to match with
 *
 * Check if the EDID matches with the given identity.
 *
 * Return: True if the given identity matched with EDID, false otherwise.
 */
bool drm_edid_match(const struct drm_edid *drm_edid,
		    const struct drm_edid_ident *ident)
{}
EXPORT_SYMBOL();

static void
monitor_name(const struct detailed_timing *timing, void *data)
{}

static int get_monitor_name(const struct drm_edid *drm_edid, char name[13])
{}

/**
 * drm_edid_get_monitor_name - fetch the monitor name from the edid
 * @edid: monitor EDID information
 * @name: pointer to a character array to hold the name of the monitor
 * @bufsize: The size of the name buffer (should be at least 14 chars.)
 *
 */
void drm_edid_get_monitor_name(const struct edid *edid, char *name, int bufsize)
{}
EXPORT_SYMBOL();

static void clear_eld(struct drm_connector *connector)
{}

/*
 * Get 3-byte SAD buffer from struct cea_sad.
 */
void drm_edid_cta_sad_get(const struct cea_sad *cta_sad, u8 *sad)
{}

/*
 * Set struct cea_sad from 3-byte SAD buffer.
 */
void drm_edid_cta_sad_set(struct cea_sad *cta_sad, const u8 *sad)
{}

/*
 * drm_edid_to_eld - build ELD from EDID
 * @connector: connector corresponding to the HDMI/DP sink
 * @drm_edid: EDID to parse
 *
 * Fill the ELD (EDID-Like Data) buffer for passing to the audio driver. The
 * HDCP and Port_ID ELD fields are left for the graphics driver to fill in.
 */
static void drm_edid_to_eld(struct drm_connector *connector,
			    const struct drm_edid *drm_edid)
{}

static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
			    struct cea_sad **psads)
{}

/**
 * drm_edid_to_sad - extracts SADs from EDID
 * @edid: EDID to parse
 * @sads: pointer that will be set to the extracted SADs
 *
 * Looks for CEA EDID block and extracts SADs (Short Audio Descriptors) from it.
 *
 * Note: The returned pointer needs to be freed using kfree().
 *
 * Return: The number of found SADs or negative number on error.
 */
int drm_edid_to_sad(const struct edid *edid, struct cea_sad **sads)
{}
EXPORT_SYMBOL();

static int _drm_edid_to_speaker_allocation(const struct drm_edid *drm_edid,
					   u8 **sadb)
{}

/**
 * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID
 * @edid: EDID to parse
 * @sadb: pointer to the speaker block
 *
 * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it.
 *
 * Note: The returned pointer needs to be freed using kfree().
 *
 * Return: The number of found Speaker Allocation Blocks or negative number on
 * error.
 */
int drm_edid_to_speaker_allocation(const struct edid *edid, u8 **sadb)
{}
EXPORT_SYMBOL();

/**
 * drm_av_sync_delay - compute the HDMI/DP sink audio-video sync delay
 * @connector: connector associated with the HDMI/DP sink
 * @mode: the display mode
 *
 * Return: The HDMI/DP sink's audio-video sync delay in milliseconds or 0 if
 * the sink doesn't support audio or video.
 */
int drm_av_sync_delay(struct drm_connector *connector,
		      const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

static bool _drm_detect_hdmi_monitor(const struct drm_edid *drm_edid)
{}

/**
 * drm_detect_hdmi_monitor - detect whether monitor is HDMI
 * @edid: monitor EDID information
 *
 * Parse the CEA extension according to CEA-861-B.
 *
 * Drivers that have added the modes parsed from EDID to drm_display_info
 * should use &drm_display_info.is_hdmi instead of calling this function.
 *
 * Return: True if the monitor is HDMI, false if not or unknown.
 */
bool drm_detect_hdmi_monitor(const struct edid *edid)
{}
EXPORT_SYMBOL();

static bool _drm_detect_monitor_audio(const struct drm_edid *drm_edid)
{}

/**
 * drm_detect_monitor_audio - check monitor audio capability
 * @edid: EDID block to scan
 *
 * Monitor should have CEA extension block.
 * If monitor has 'basic audio', but no CEA audio blocks, it's 'basic
 * audio' only. If there is any audio extension block and supported
 * audio format, assume at least 'basic audio' support, even if 'basic
 * audio' is not defined in EDID.
 *
 * Return: True if the monitor supports audio, false otherwise.
 */
bool drm_detect_monitor_audio(const struct edid *edid)
{}
EXPORT_SYMBOL();


/**
 * drm_default_rgb_quant_range - default RGB quantization range
 * @mode: display mode
 *
 * Determine the default RGB quantization range for the mode,
 * as specified in CEA-861.
 *
 * Return: The default RGB quantization range for the mode
 */
enum hdmi_quantization_range
drm_default_rgb_quant_range(const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/* CTA-861 Video Data Block (CTA VDB) */
static void parse_cta_vdb(struct drm_connector *connector, const struct cea_db *db)
{}

/*
 * Update y420_cmdb_modes based on previously parsed CTA VDB and Y420CMDB.
 *
 * Translate the y420cmdb_map based on VIC indexes to y420_cmdb_modes indexed
 * using the VICs themselves.
 */
static void update_cta_y420cmdb(struct drm_connector *connector, u64 y420cmdb_map)
{}

static bool cta_vdb_has_vic(const struct drm_connector *connector, u8 vic)
{}

/* CTA-861-H YCbCr 4:2:0 Video Data Block (CTA Y420VDB) */
static void parse_cta_y420vdb(struct drm_connector *connector,
			      const struct cea_db *db)
{}

static void drm_parse_vcdb(struct drm_connector *connector, const u8 *db)
{}

static
void drm_get_max_frl_rate(int max_frl_rate, u8 *max_lanes, u8 *max_rate_per_lane)
{}

static void drm_parse_ycbcr420_deep_color_info(struct drm_connector *connector,
					       const u8 *db)
{}

static void drm_parse_dsc_info(struct drm_hdmi_dsc_cap *hdmi_dsc,
			       const u8 *hf_scds)
{}

/* Sink Capability Data Structure */
static void drm_parse_hdmi_forum_scds(struct drm_connector *connector,
				      const u8 *hf_scds)
{}

static void drm_parse_hdmi_deep_color_info(struct drm_connector *connector,
					   const u8 *hdmi)
{}

/* HDMI Vendor-Specific Data Block (HDMI VSDB, H14b-VSDB) */
static void
drm_parse_hdmi_vsdb_video(struct drm_connector *connector, const u8 *db)
{}

/*
 * See EDID extension for head-mounted and specialized monitors, specified at:
 * https://docs.microsoft.com/en-us/windows-hardware/drivers/display/specialized-monitors-edid-extension
 */
static void drm_parse_microsoft_vsdb(struct drm_connector *connector,
				     const u8 *db)
{}

static void drm_parse_cea_ext(struct drm_connector *connector,
			      const struct drm_edid *drm_edid)
{}

static
void get_monitor_range(const struct detailed_timing *timing, void *c)
{}

static void drm_get_monitor_range(struct drm_connector *connector,
				  const struct drm_edid *drm_edid)
{}

static void drm_parse_vesa_mso_data(struct drm_connector *connector,
				    const struct displayid_block *block)
{}

static void drm_update_mso(struct drm_connector *connector,
			   const struct drm_edid *drm_edid)
{}

/* A connector has no EDID information, so we've got no EDID to compute quirks from. Reset
 * all of the values which would have been set from EDID
 */
static void drm_reset_display_info(struct drm_connector *connector)
{}

static void update_displayid_info(struct drm_connector *connector,
				  const struct drm_edid *drm_edid)
{}

static void update_display_info(struct drm_connector *connector,
				const struct drm_edid *drm_edid)
{}

static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *dev,
							    struct displayid_detailed_timings_1 *timings,
							    bool type_7)
{}

static int add_displayid_detailed_1_modes(struct drm_connector *connector,
					  const struct displayid_block *block)
{}

static int add_displayid_detailed_modes(struct drm_connector *connector,
					const struct drm_edid *drm_edid)
{}

static int _drm_edid_connector_add_modes(struct drm_connector *connector,
					 const struct drm_edid *drm_edid)
{}

static void _drm_update_tile_info(struct drm_connector *connector,
				  const struct drm_edid *drm_edid);

static int _drm_edid_connector_property_update(struct drm_connector *connector,
					       const struct drm_edid *drm_edid)
{}

/* For sysfs edid show implementation */
ssize_t drm_edid_connector_property_show(struct drm_connector *connector,
					 char *buf, loff_t off, size_t count)
{}

/**
 * drm_edid_connector_update - Update connector information from EDID
 * @connector: Connector
 * @drm_edid: EDID
 *
 * Update the connector display info, ELD, HDR metadata, relevant properties,
 * etc. from the passed in EDID.
 *
 * If EDID is NULL, reset the information.
 *
 * Must be called before calling drm_edid_connector_add_modes().
 *
 * Return: 0 on success, negative error on errors.
 */
int drm_edid_connector_update(struct drm_connector *connector,
			      const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();

/**
 * drm_edid_connector_add_modes - Update probed modes from the EDID property
 * @connector: Connector
 *
 * Add the modes from the previously updated EDID property to the connector
 * probed modes list.
 *
 * drm_edid_connector_update() must have been called before this to update the
 * EDID property.
 *
 * Return: The number of modes added, or 0 if we couldn't find any.
 */
int drm_edid_connector_add_modes(struct drm_connector *connector)
{}
EXPORT_SYMBOL();

/**
 * drm_connector_update_edid_property - update the edid property of a connector
 * @connector: drm connector
 * @edid: new value of the edid property
 *
 * This function creates a new blob modeset object and assigns its id to the
 * connector's edid property.
 * Since we also parse tile information from EDID's displayID block, we also
 * set the connector's tile property here. See drm_connector_set_tile_property()
 * for more details.
 *
 * This function is deprecated. Use drm_edid_connector_update() instead.
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
int drm_connector_update_edid_property(struct drm_connector *connector,
				       const struct edid *edid)
{}
EXPORT_SYMBOL();

/**
 * drm_add_edid_modes - add modes from EDID data, if available
 * @connector: connector we're probing
 * @edid: EDID data
 *
 * Add the specified modes to the connector's mode list. Also fills out the
 * &drm_display_info structure and ELD in @connector with any information which
 * can be derived from the edid.
 *
 * This function is deprecated. Use drm_edid_connector_add_modes() instead.
 *
 * Return: The number of modes added or 0 if we couldn't find any.
 */
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
{}
EXPORT_SYMBOL();

/**
 * drm_add_modes_noedid - add modes for the connectors without EDID
 * @connector: connector we're probing
 * @hdisplay: the horizontal display limit
 * @vdisplay: the vertical display limit
 *
 * Add the specified modes to the connector's mode list. Only when the
 * hdisplay/vdisplay is not beyond the given limit, it will be added.
 *
 * Return: The number of modes added or 0 if we couldn't find any.
 */
int drm_add_modes_noedid(struct drm_connector *connector,
			int hdisplay, int vdisplay)
{}
EXPORT_SYMBOL();

static bool is_hdmi2_sink(const struct drm_connector *connector)
{}

static u8 drm_mode_hdmi_vic(const struct drm_connector *connector,
			    const struct drm_display_mode *mode)
{}

static u8 drm_mode_cea_vic(const struct drm_connector *connector,
			   const struct drm_display_mode *mode)
{}

/*
 * Avoid sending VICs defined in HDMI 2.0 in AVI infoframes to sinks that
 * conform to HDMI 1.4.
 *
 * HDMI 1.4 (CTA-861-D) VIC range: [1..64]
 * HDMI 2.0 (CTA-861-F) VIC range: [1..107]
 *
 * If the sink lists the VIC in CTA VDB, assume it's fine, regardless of HDMI
 * version.
 */
static u8 vic_for_avi_infoframe(const struct drm_connector *connector, u8 vic)
{}

/**
 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
 *                                              data from a DRM display mode
 * @frame: HDMI AVI infoframe
 * @connector: the connector
 * @mode: DRM display mode
 *
 * Return: 0 on success or a negative error code on failure.
 */
int
drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
					 const struct drm_connector *connector,
					 const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe
 *                                        quantization range information
 * @frame: HDMI AVI infoframe
 * @connector: the connector
 * @mode: DRM display mode
 * @rgb_quant_range: RGB quantization range (Q)
 */
void
drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame,
				   const struct drm_connector *connector,
				   const struct drm_display_mode *mode,
				   enum hdmi_quantization_range rgb_quant_range)
{}
EXPORT_SYMBOL();

static enum hdmi_3d_structure
s3d_structure_from_display_mode(const struct drm_display_mode *mode)
{}

/**
 * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with
 * data from a DRM display mode
 * @frame: HDMI vendor infoframe
 * @connector: the connector
 * @mode: DRM display mode
 *
 * Note that there's is a need to send HDMI vendor infoframes only when using a
 * 4k or stereoscopic 3D mode. So when giving any other mode as input this
 * function will return -EINVAL, error that can be safely ignored.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int
drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame,
					    const struct drm_connector *connector,
					    const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

static void drm_parse_tiled_block(struct drm_connector *connector,
				  const struct displayid_block *block)
{}

static bool displayid_is_tiled_block(const struct displayid_iter *iter,
				     const struct displayid_block *block)
{}

static void _drm_update_tile_info(struct drm_connector *connector,
				  const struct drm_edid *drm_edid)
{}

/**
 * drm_edid_is_digital - is digital?
 * @drm_edid: The EDID
 *
 * Return true if input is digital.
 */
bool drm_edid_is_digital(const struct drm_edid *drm_edid)
{}
EXPORT_SYMBOL();