linux/drivers/gpu/drm/drm_modes.c

/*
 * Copyright © 1997-2003 by The XFree86 Project, Inc.
 * Copyright © 2007 Dave Airlie
 * Copyright © 2007-2008 Intel Corporation
 *   Jesse Barnes <[email protected]>
 * Copyright 2005-2006 Luc Verhaegen
 * Copyright (c) 2001, Andy Ritger  [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, sublicense,
 * 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 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 NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Except as contained in this notice, the name of the copyright holder(s)
 * and author(s) shall not be used in advertising or otherwise to promote
 * the sale, use or other dealings in this Software without prior written
 * authorization from the copyright holder(s) and author(s).
 */

#include <linux/ctype.h>
#include <linux/export.h>
#include <linux/fb.h> /* for KHZ2PICOS() */
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/of.h>

#include <video/of_display_timing.h>
#include <video/of_videomode.h>
#include <video/videomode.h>

#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_modes.h>
#include <drm/drm_print.h>

#include "drm_crtc_internal.h"

/**
 * drm_mode_debug_printmodeline - print a mode to dmesg
 * @mode: mode to print
 *
 * Describe @mode using DRM_DEBUG.
 */
void drm_mode_debug_printmodeline(const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_create - create a new display mode
 * @dev: DRM device
 *
 * Create a new, cleared drm_display_mode with kzalloc, allocate an ID for it
 * and return it.
 *
 * Returns:
 * Pointer to new mode on success, NULL on error.
 */
struct drm_display_mode *drm_mode_create(struct drm_device *dev)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_destroy - remove a mode
 * @dev: DRM device
 * @mode: mode to remove
 *
 * Release @mode's unique ID, then free it @mode structure itself using kfree.
 */
void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_probed_add - add a mode to a connector's probed_mode list
 * @connector: connector the new mode
 * @mode: mode data
 *
 * Add @mode to @connector's probed_mode list for later use. This list should
 * then in a second step get filtered and all the modes actually supported by
 * the hardware moved to the @connector's modes list.
 */
void drm_mode_probed_add(struct drm_connector *connector,
			 struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

enum drm_mode_analog {};

/*
 * The timings come from:
 * - https://web.archive.org/web/20220406232708/http://www.kolumbus.fi/pami1/video/pal_ntsc.html
 * - https://web.archive.org/web/20220406124914/http://martin.hinner.info/vga/pal.html
 * - https://web.archive.org/web/20220609202433/http://www.batsocks.co.uk/readme/video_timing.htm
 */
#define NTSC_LINE_DURATION_NS
#define NTSC_LINES_NUMBER

#define NTSC_HBLK_DURATION_TYP_NS
#define NTSC_HBLK_DURATION_MIN_NS
#define NTSC_HBLK_DURATION_MAX_NS

#define NTSC_HACT_DURATION_TYP_NS
#define NTSC_HACT_DURATION_MIN_NS
#define NTSC_HACT_DURATION_MAX_NS

#define NTSC_HFP_DURATION_TYP_NS
#define NTSC_HFP_DURATION_MIN_NS
#define NTSC_HFP_DURATION_MAX_NS

#define NTSC_HSLEN_DURATION_TYP_NS
#define NTSC_HSLEN_DURATION_MIN_NS
#define NTSC_HSLEN_DURATION_MAX_NS

#define NTSC_HBP_DURATION_TYP_NS

/*
 * I couldn't find the actual tolerance for the back porch, so let's
 * just reuse the sync length ones.
 */
#define NTSC_HBP_DURATION_MIN_NS
#define NTSC_HBP_DURATION_MAX_NS

#define PAL_LINE_DURATION_NS
#define PAL_LINES_NUMBER

#define PAL_HACT_DURATION_TYP_NS
#define PAL_HACT_DURATION_MIN_NS
#define PAL_HACT_DURATION_MAX_NS

#define PAL_HBLK_DURATION_TYP_NS
#define PAL_HBLK_DURATION_MIN_NS
#define PAL_HBLK_DURATION_MAX_NS

#define PAL_HFP_DURATION_TYP_NS
#define PAL_HFP_DURATION_MIN_NS
#define PAL_HFP_DURATION_MAX_NS

#define PAL_HSLEN_DURATION_TYP_NS
#define PAL_HSLEN_DURATION_MIN_NS
#define PAL_HSLEN_DURATION_MAX_NS

#define PAL_HBP_DURATION_TYP_NS
#define PAL_HBP_DURATION_MIN_NS
#define PAL_HBP_DURATION_MAX_NS

struct analog_param_field {};

#define PARAM_FIELD(_odd, _even)

struct analog_param_range {};

#define PARAM_RANGE(_min, _typ, _max)

struct analog_parameters {};

#define TV_MODE_PARAMETER(_mode, _lines, _line_dur, _hact, _hfp,	\
			  _hslen, _hbp, _hblk, _bt601_hfp, _vfp,	\
			  _vslen, _vbp)

static const struct analog_parameters tv_modes_parameters[] =;

static int fill_analog_mode(struct drm_device *dev,
			    struct drm_display_mode *mode,
			    const struct analog_parameters *params,
			    unsigned long pixel_clock_hz,
			    unsigned int hactive,
			    unsigned int vactive,
			    bool interlace)
{}

/**
 * drm_analog_tv_mode - create a display mode for an analog TV
 * @dev: drm device
 * @tv_mode: TV Mode standard to create a mode for. See DRM_MODE_TV_MODE_*.
 * @pixel_clock_hz: Pixel Clock Frequency, in Hertz
 * @hdisplay: hdisplay size
 * @vdisplay: vdisplay size
 * @interlace: whether to compute an interlaced mode
 *
 * This function creates a struct drm_display_mode instance suited for
 * an analog TV output, for one of the usual analog TV modes. Where
 * this is DRM_MODE_TV_MODE_MONOCHROME, a 625-line mode will be created.
 *
 * Note that @hdisplay is larger than the usual constraints for the PAL
 * and NTSC timings, and we'll choose to ignore most timings constraints
 * to reach those resolutions.
 *
 * Returns:
 *
 * A pointer to the mode, allocated with drm_mode_create(). Returns NULL
 * on error.
 */
struct drm_display_mode *drm_analog_tv_mode(struct drm_device *dev,
					    enum drm_connector_tv_mode tv_mode,
					    unsigned long pixel_clock_hz,
					    unsigned int hdisplay,
					    unsigned int vdisplay,
					    bool interlace)
{}
EXPORT_SYMBOL();

/**
 * drm_cvt_mode -create a modeline based on the CVT algorithm
 * @dev: drm device
 * @hdisplay: hdisplay size
 * @vdisplay: vdisplay size
 * @vrefresh: vrefresh rate
 * @reduced: whether to use reduced blanking
 * @interlaced: whether to compute an interlaced mode
 * @margins: whether to add margins (borders)
 *
 * This function is called to generate the modeline based on CVT algorithm
 * according to the hdisplay, vdisplay, vrefresh.
 * It is based from the VESA(TM) Coordinated Video Timing Generator by
 * Graham Loveridge April 9, 2003 available at
 * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls
 *
 * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c.
 * What I have done is to translate it by using integer calculation.
 *
 * Returns:
 * The modeline based on the CVT algorithm stored in a drm_display_mode object.
 * The display mode object is allocated with drm_mode_create(). Returns NULL
 * when no mode could be allocated.
 */
struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
				      int vdisplay, int vrefresh,
				      bool reduced, bool interlaced, bool margins)
{}
EXPORT_SYMBOL();

/**
 * drm_gtf_mode_complex - create the modeline based on the full GTF algorithm
 * @dev: drm device
 * @hdisplay: hdisplay size
 * @vdisplay: vdisplay size
 * @vrefresh: vrefresh rate.
 * @interlaced: whether to compute an interlaced mode
 * @margins: desired margin (borders) size
 * @GTF_M: extended GTF formula parameters
 * @GTF_2C: extended GTF formula parameters
 * @GTF_K: extended GTF formula parameters
 * @GTF_2J: extended GTF formula parameters
 *
 * GTF feature blocks specify C and J in multiples of 0.5, so we pass them
 * in here multiplied by two.  For a C of 40, pass in 80.
 *
 * Returns:
 * The modeline based on the full GTF algorithm stored in a drm_display_mode object.
 * The display mode object is allocated with drm_mode_create(). Returns NULL
 * when no mode could be allocated.
 */
struct drm_display_mode *
drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay,
		     int vrefresh, bool interlaced, int margins,
		     int GTF_M, int GTF_2C, int GTF_K, int GTF_2J)
{}
EXPORT_SYMBOL();

/**
 * drm_gtf_mode - create the modeline based on the GTF algorithm
 * @dev: drm device
 * @hdisplay: hdisplay size
 * @vdisplay: vdisplay size
 * @vrefresh: vrefresh rate.
 * @interlaced: whether to compute an interlaced mode
 * @margins: desired margin (borders) size
 *
 * return the modeline based on GTF algorithm
 *
 * This function is to create the modeline based on the GTF algorithm.
 * Generalized Timing Formula is derived from:
 *
 *	GTF Spreadsheet by Andy Morrish (1/5/97)
 *	available at https://www.vesa.org
 *
 * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c.
 * What I have done is to translate it by using integer calculation.
 * I also refer to the function of fb_get_mode in the file of
 * drivers/video/fbmon.c
 *
 * Standard GTF parameters::
 *
 *     M = 600
 *     C = 40
 *     K = 128
 *     J = 20
 *
 * Returns:
 * The modeline based on the GTF algorithm stored in a drm_display_mode object.
 * The display mode object is allocated with drm_mode_create(). Returns NULL
 * when no mode could be allocated.
 */
struct drm_display_mode *
drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh,
	     bool interlaced, int margins)
{}
EXPORT_SYMBOL();

#ifdef CONFIG_VIDEOMODE_HELPERS
/**
 * drm_display_mode_from_videomode - fill in @dmode using @vm,
 * @vm: videomode structure to use as source
 * @dmode: drm_display_mode structure to use as destination
 *
 * Fills out @dmode using the display mode specified in @vm.
 */
void drm_display_mode_from_videomode(const struct videomode *vm,
				     struct drm_display_mode *dmode)
{}
EXPORT_SYMBOL_GPL();

/**
 * drm_display_mode_to_videomode - fill in @vm using @dmode,
 * @dmode: drm_display_mode structure to use as source
 * @vm: videomode structure to use as destination
 *
 * Fills out @vm using the display mode specified in @dmode.
 */
void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
				   struct videomode *vm)
{}
EXPORT_SYMBOL_GPL();

/**
 * drm_bus_flags_from_videomode - extract information about pixelclk and
 * DE polarity from videomode and store it in a separate variable
 * @vm: videomode structure to use
 * @bus_flags: information about pixelclk, sync and DE polarity will be stored
 * here
 *
 * Sets DRM_BUS_FLAG_DE_(LOW|HIGH),  DRM_BUS_FLAG_PIXDATA_DRIVE_(POS|NEG)EDGE
 * and DISPLAY_FLAGS_SYNC_(POS|NEG)EDGE in @bus_flags according to DISPLAY_FLAGS
 * found in @vm
 */
void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_OF
/**
 * of_get_drm_display_mode - get a drm_display_mode from devicetree
 * @np: device_node with the timing specification
 * @dmode: will be set to the return value
 * @bus_flags: information about pixelclk, sync and DE polarity
 * @index: index into the list of display timings in devicetree
 *
 * This function is expensive and should only be used, if only one mode is to be
 * read from DT. To get multiple modes start with of_get_display_timings and
 * work with that instead.
 *
 * Returns:
 * 0 on success, a negative errno code when no of videomode node was found.
 */
int of_get_drm_display_mode(struct device_node *np,
			    struct drm_display_mode *dmode, u32 *bus_flags,
			    int index)
{}
EXPORT_SYMBOL_GPL();

/**
 * of_get_drm_panel_display_mode - get a panel-timing drm_display_mode from devicetree
 * @np: device_node with the panel-timing specification
 * @dmode: will be set to the return value
 * @bus_flags: information about pixelclk, sync and DE polarity
 *
 * The mandatory Device Tree properties width-mm and height-mm
 * are read and set on the display mode.
 *
 * Returns:
 * Zero on success, negative error code on failure.
 */
int of_get_drm_panel_display_mode(struct device_node *np,
				  struct drm_display_mode *dmode, u32 *bus_flags)
{}
EXPORT_SYMBOL_GPL();
#endif /* CONFIG_OF */
#endif /* CONFIG_VIDEOMODE_HELPERS */

/**
 * drm_mode_set_name - set the name on a mode
 * @mode: name will be set in this mode
 *
 * Set the name of @mode to a standard format which is <hdisplay>x<vdisplay>
 * with an optional 'i' suffix for interlaced modes.
 */
void drm_mode_set_name(struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_vrefresh - get the vrefresh of a mode
 * @mode: mode
 *
 * Returns:
 * @modes's vrefresh rate in Hz, rounded to the nearest integer. Calculates the
 * value first if it is not yet set.
 */
int drm_mode_vrefresh(const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_get_hv_timing - Fetches hdisplay/vdisplay for given mode
 * @mode: mode to query
 * @hdisplay: hdisplay value to fill in
 * @vdisplay: vdisplay value to fill in
 *
 * The vdisplay value will be doubled if the specified mode is a stereo mode of
 * the appropriate layout.
 */
void drm_mode_get_hv_timing(const struct drm_display_mode *mode,
			    int *hdisplay, int *vdisplay)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_set_crtcinfo - set CRTC modesetting timing parameters
 * @p: mode
 * @adjust_flags: a combination of adjustment flags
 *
 * Setup the CRTC modesetting timing parameters for @p, adjusting if necessary.
 *
 * - The CRTC_INTERLACE_HALVE_V flag can be used to halve vertical timings of
 *   interlaced modes.
 * - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for
 *   buffers containing two eyes (only adjust the timings when needed, eg. for
 *   "frame packing" or "side by side full").
 * - The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment *not*
 *   be performed for doublescan and vscan > 1 modes respectively.
 */
void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_copy - copy the mode
 * @dst: mode to overwrite
 * @src: mode to copy
 *
 * Copy an existing mode into another mode, preserving the
 * list head of the destination mode.
 */
void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_init - initialize the mode from another mode
 * @dst: mode to overwrite
 * @src: mode to copy
 *
 * Copy an existing mode into another mode, zeroing the
 * list head of the destination mode. Typically used
 * to guarantee the list head is not left with stack
 * garbage in on-stack modes.
 */
void drm_mode_init(struct drm_display_mode *dst, const struct drm_display_mode *src)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_duplicate - allocate and duplicate an existing mode
 * @dev: drm_device to allocate the duplicated mode for
 * @mode: mode to duplicate
 *
 * Just allocate a new mode, copy the existing mode into it, and return
 * a pointer to it.  Used to create new instances of established modes.
 *
 * Returns:
 * Pointer to duplicated mode on success, NULL on error.
 */
struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
					    const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

static bool drm_mode_match_timings(const struct drm_display_mode *mode1,
				   const struct drm_display_mode *mode2)
{}

static bool drm_mode_match_clock(const struct drm_display_mode *mode1,
				  const struct drm_display_mode *mode2)
{}

static bool drm_mode_match_flags(const struct drm_display_mode *mode1,
				 const struct drm_display_mode *mode2)
{}

static bool drm_mode_match_3d_flags(const struct drm_display_mode *mode1,
				    const struct drm_display_mode *mode2)
{}

static bool drm_mode_match_aspect_ratio(const struct drm_display_mode *mode1,
					const struct drm_display_mode *mode2)
{}

/**
 * drm_mode_match - test modes for (partial) equality
 * @mode1: first mode
 * @mode2: second mode
 * @match_flags: which parts need to match (DRM_MODE_MATCH_*)
 *
 * Check to see if @mode1 and @mode2 are equivalent.
 *
 * Returns:
 * True if the modes are (partially) equal, false otherwise.
 */
bool drm_mode_match(const struct drm_display_mode *mode1,
		    const struct drm_display_mode *mode2,
		    unsigned int match_flags)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_equal - test modes for equality
 * @mode1: first mode
 * @mode2: second mode
 *
 * Check to see if @mode1 and @mode2 are equivalent.
 *
 * Returns:
 * True if the modes are equal, false otherwise.
 */
bool drm_mode_equal(const struct drm_display_mode *mode1,
		    const struct drm_display_mode *mode2)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_equal_no_clocks - test modes for equality
 * @mode1: first mode
 * @mode2: second mode
 *
 * Check to see if @mode1 and @mode2 are equivalent, but
 * don't check the pixel clocks.
 *
 * Returns:
 * True if the modes are equal, false otherwise.
 */
bool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
			      const struct drm_display_mode *mode2)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_equal_no_clocks_no_stereo - test modes for equality
 * @mode1: first mode
 * @mode2: second mode
 *
 * Check to see if @mode1 and @mode2 are equivalent, but
 * don't check the pixel clocks nor the stereo layout.
 *
 * Returns:
 * True if the modes are equal, false otherwise.
 */
bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
					const struct drm_display_mode *mode2)
{}
EXPORT_SYMBOL();

static enum drm_mode_status
drm_mode_validate_basic(const struct drm_display_mode *mode)
{}

/**
 * drm_mode_validate_driver - make sure the mode is somewhat sane
 * @dev: drm device
 * @mode: mode to check
 *
 * First do basic validation on the mode, and then allow the driver
 * to check for device/driver specific limitations via the optional
 * &drm_mode_config_helper_funcs.mode_valid hook.
 *
 * Returns:
 * The mode status
 */
enum drm_mode_status
drm_mode_validate_driver(struct drm_device *dev,
			const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_validate_size - make sure modes adhere to size constraints
 * @mode: mode to check
 * @maxX: maximum width
 * @maxY: maximum height
 *
 * This function is a helper which can be used to validate modes against size
 * limitations of the DRM device/connector. If a mode is too big its status
 * member is updated with the appropriate validation failure code. The list
 * itself is not changed.
 *
 * Returns:
 * The mode status
 */
enum drm_mode_status
drm_mode_validate_size(const struct drm_display_mode *mode,
		       int maxX, int maxY)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_validate_ycbcr420 - add 'ycbcr420-only' modes only when allowed
 * @mode: mode to check
 * @connector: drm connector under action
 *
 * This function is a helper which can be used to filter out any YCBCR420
 * only mode, when the source doesn't support it.
 *
 * Returns:
 * The mode status
 */
enum drm_mode_status
drm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
			   struct drm_connector *connector)
{}
EXPORT_SYMBOL();

#define MODE_STATUS

static const char * const drm_mode_status_names[] =;

#undef MODE_STATUS

const char *drm_get_mode_status_name(enum drm_mode_status status)
{}

/**
 * drm_mode_prune_invalid - remove invalid modes from mode list
 * @dev: DRM device
 * @mode_list: list of modes to check
 * @verbose: be verbose about it
 *
 * This helper function can be used to prune a display mode list after
 * validation has been completed. All modes whose status is not MODE_OK will be
 * removed from the list, and if @verbose the status code and mode name is also
 * printed to dmesg.
 */
void drm_mode_prune_invalid(struct drm_device *dev,
			    struct list_head *mode_list, bool verbose)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_compare - compare modes for favorability
 * @priv: unused
 * @lh_a: list_head for first mode
 * @lh_b: list_head for second mode
 *
 * Compare two modes, given by @lh_a and @lh_b, returning a value indicating
 * which is better.
 *
 * Returns:
 * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or
 * positive if @lh_b is better than @lh_a.
 */
static int drm_mode_compare(void *priv, const struct list_head *lh_a,
			    const struct list_head *lh_b)
{}

/**
 * drm_mode_sort - sort mode list
 * @mode_list: list of drm_display_mode structures to sort
 *
 * Sort @mode_list by favorability, moving good modes to the head of the list.
 */
void drm_mode_sort(struct list_head *mode_list)
{}
EXPORT_SYMBOL();

/**
 * drm_connector_list_update - update the mode list for the connector
 * @connector: the connector to update
 *
 * This moves the modes from the @connector probed_modes list
 * to the actual mode list. It compares the probed mode against the current
 * list and only adds different/new modes.
 *
 * This is just a helper functions doesn't validate any modes itself and also
 * doesn't prune any invalid modes. Callers need to do that themselves.
 */
void drm_connector_list_update(struct drm_connector *connector)
{}
EXPORT_SYMBOL();

static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr,
				      struct drm_cmdline_mode *mode)
{}

static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
					  struct drm_cmdline_mode *mode)
{}

static int drm_mode_parse_cmdline_extra(const char *str, int length,
					bool freestanding,
					const struct drm_connector *connector,
					struct drm_cmdline_mode *mode)
{}

static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
					   bool extras,
					   const struct drm_connector *connector,
					   struct drm_cmdline_mode *mode)
{}

static int drm_mode_parse_cmdline_int(const char *delim, unsigned int *int_ret)
{}

static int drm_mode_parse_panel_orientation(const char *delim,
					    struct drm_cmdline_mode *mode)
{}

static int drm_mode_parse_tv_mode(const char *delim,
				  struct drm_cmdline_mode *mode)
{}

static int drm_mode_parse_cmdline_options(const char *str,
					  bool freestanding,
					  const struct drm_connector *connector,
					  struct drm_cmdline_mode *mode)
{}

struct drm_named_mode {};

#define NAMED_MODE(_name, _pclk, _x, _y, _flags, _mode)

static const struct drm_named_mode drm_named_modes[] =;

static int drm_mode_parse_cmdline_named_mode(const char *name,
					     unsigned int name_end,
					     struct drm_cmdline_mode *cmdline_mode)
{}

/**
 * drm_mode_parse_command_line_for_connector - parse command line modeline for connector
 * @mode_option: optional per connector mode option
 * @connector: connector to parse modeline for
 * @mode: preallocated drm_cmdline_mode structure to fill out
 *
 * This parses @mode_option command line modeline for modes and options to
 * configure the connector.
 *
 * This uses the same parameters as the fb modedb.c, except for an extra
 * force-enable, force-enable-digital and force-disable bit at the end::
 *
 *	<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
 *
 * Additionals options can be provided following the mode, using a comma to
 * separate each option. Valid options can be found in
 * Documentation/fb/modedb.rst.
 *
 * The intermediate drm_cmdline_mode structure is required to store additional
 * options from the command line modline like the force-enable/disable flag.
 *
 * Returns:
 * True if a valid modeline has been parsed, false otherwise.
 */
bool drm_mode_parse_command_line_for_connector(const char *mode_option,
					       const struct drm_connector *connector,
					       struct drm_cmdline_mode *mode)
{}
EXPORT_SYMBOL();

static struct drm_display_mode *drm_named_mode(struct drm_device *dev,
					       struct drm_cmdline_mode *cmd)
{}

/**
 * drm_mode_create_from_cmdline_mode - convert a command line modeline into a DRM display mode
 * @dev: DRM device to create the new mode for
 * @cmd: input command line modeline
 *
 * Returns:
 * Pointer to converted mode on success, NULL on error.
 */
struct drm_display_mode *
drm_mode_create_from_cmdline_mode(struct drm_device *dev,
				  struct drm_cmdline_mode *cmd)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_convert_to_umode - convert a drm_display_mode into a modeinfo
 * @out: drm_mode_modeinfo struct to return to the user
 * @in: drm_display_mode to use
 *
 * Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
 * the user.
 */
void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
			       const struct drm_display_mode *in)
{}

/**
 * drm_mode_convert_umode - convert a modeinfo into a drm_display_mode
 * @dev: drm device
 * @out: drm_display_mode to return to the user
 * @in: drm_mode_modeinfo to use
 *
 * Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
 * the caller.
 *
 * Returns:
 * Zero on success, negative errno on failure.
 */
int drm_mode_convert_umode(struct drm_device *dev,
			   struct drm_display_mode *out,
			   const struct drm_mode_modeinfo *in)
{}

/**
 * drm_mode_is_420_only - if a given videomode can be only supported in YCBCR420
 * output format
 *
 * @display: display under action
 * @mode: video mode to be tested.
 *
 * Returns:
 * true if the mode can be supported in YCBCR420 format
 * false if not.
 */
bool drm_mode_is_420_only(const struct drm_display_info *display,
			  const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_mode_is_420_also - if a given videomode can be supported in YCBCR420
 * output format also (along with RGB/YCBCR444/422)
 *
 * @display: display under action.
 * @mode: video mode to be tested.
 *
 * Returns:
 * true if the mode can be support YCBCR420 format
 * false if not.
 */
bool drm_mode_is_420_also(const struct drm_display_info *display,
			  const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();
/**
 * drm_mode_is_420 - if a given videomode can be supported in YCBCR420
 * output format
 *
 * @display: display under action.
 * @mode: video mode to be tested.
 *
 * Returns:
 * true if the mode can be supported in YCBCR420 format
 * false if not.
 */
bool drm_mode_is_420(const struct drm_display_info *display,
		     const struct drm_display_mode *mode)
{}
EXPORT_SYMBOL();

/**
 * drm_set_preferred_mode - Sets the preferred mode of a connector
 * @connector: connector whose mode list should be processed
 * @hpref: horizontal resolution of preferred mode
 * @vpref: vertical resolution of preferred mode
 *
 * Marks a mode as preferred if it matches the resolution specified by @hpref
 * and @vpref.
 */
void drm_set_preferred_mode(struct drm_connector *connector,
			    int hpref, int vpref)
{}
EXPORT_SYMBOL();