162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Copyright © 2006 Keith Packard
362306a36Sopenharmony_ci * Copyright © 2007-2008 Dave Airlie
462306a36Sopenharmony_ci * Copyright © 2007-2008 Intel Corporation
562306a36Sopenharmony_ci *   Jesse Barnes <jesse.barnes@intel.com>
662306a36Sopenharmony_ci * Copyright © 2014 Intel Corporation
762306a36Sopenharmony_ci *   Daniel Vetter <daniel.vetter@ffwll.ch>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
1062306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
1162306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation
1262306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1362306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
1462306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
1562306a36Sopenharmony_ci *
1662306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
1762306a36Sopenharmony_ci * all copies or substantial portions of the Software.
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2062306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2162306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2262306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2362306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2462306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2562306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
2662306a36Sopenharmony_ci */
2762306a36Sopenharmony_ci#ifndef __DRM_MODES_H__
2862306a36Sopenharmony_ci#define __DRM_MODES_H__
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#include <linux/hdmi.h>
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#include <drm/drm_mode_object.h>
3362306a36Sopenharmony_ci#include <drm/drm_connector.h>
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistruct videomode;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/*
3862306a36Sopenharmony_ci * Note on terminology:  here, for brevity and convenience, we refer to connector
3962306a36Sopenharmony_ci * control chips as 'CRTCs'.  They can control any type of connector, VGA, LVDS,
4062306a36Sopenharmony_ci * DVI, etc.  And 'screen' refers to the whole of the visible display, which
4162306a36Sopenharmony_ci * may span multiple monitors (and therefore multiple CRTC and connector
4262306a36Sopenharmony_ci * structures).
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/**
4662306a36Sopenharmony_ci * enum drm_mode_status - hardware support status of a mode
4762306a36Sopenharmony_ci * @MODE_OK: Mode OK
4862306a36Sopenharmony_ci * @MODE_HSYNC: hsync out of range
4962306a36Sopenharmony_ci * @MODE_VSYNC: vsync out of range
5062306a36Sopenharmony_ci * @MODE_H_ILLEGAL: mode has illegal horizontal timings
5162306a36Sopenharmony_ci * @MODE_V_ILLEGAL: mode has illegal vertical timings
5262306a36Sopenharmony_ci * @MODE_BAD_WIDTH: requires an unsupported linepitch
5362306a36Sopenharmony_ci * @MODE_NOMODE: no mode with a matching name
5462306a36Sopenharmony_ci * @MODE_NO_INTERLACE: interlaced mode not supported
5562306a36Sopenharmony_ci * @MODE_NO_DBLESCAN: doublescan mode not supported
5662306a36Sopenharmony_ci * @MODE_NO_VSCAN: multiscan mode not supported
5762306a36Sopenharmony_ci * @MODE_MEM: insufficient video memory
5862306a36Sopenharmony_ci * @MODE_VIRTUAL_X: mode width too large for specified virtual size
5962306a36Sopenharmony_ci * @MODE_VIRTUAL_Y: mode height too large for specified virtual size
6062306a36Sopenharmony_ci * @MODE_MEM_VIRT: insufficient video memory given virtual size
6162306a36Sopenharmony_ci * @MODE_NOCLOCK: no fixed clock available
6262306a36Sopenharmony_ci * @MODE_CLOCK_HIGH: clock required is too high
6362306a36Sopenharmony_ci * @MODE_CLOCK_LOW: clock required is too low
6462306a36Sopenharmony_ci * @MODE_CLOCK_RANGE: clock/mode isn't in a ClockRange
6562306a36Sopenharmony_ci * @MODE_BAD_HVALUE: horizontal timing was out of range
6662306a36Sopenharmony_ci * @MODE_BAD_VVALUE: vertical timing was out of range
6762306a36Sopenharmony_ci * @MODE_BAD_VSCAN: VScan value out of range
6862306a36Sopenharmony_ci * @MODE_HSYNC_NARROW: horizontal sync too narrow
6962306a36Sopenharmony_ci * @MODE_HSYNC_WIDE: horizontal sync too wide
7062306a36Sopenharmony_ci * @MODE_HBLANK_NARROW: horizontal blanking too narrow
7162306a36Sopenharmony_ci * @MODE_HBLANK_WIDE: horizontal blanking too wide
7262306a36Sopenharmony_ci * @MODE_VSYNC_NARROW: vertical sync too narrow
7362306a36Sopenharmony_ci * @MODE_VSYNC_WIDE: vertical sync too wide
7462306a36Sopenharmony_ci * @MODE_VBLANK_NARROW: vertical blanking too narrow
7562306a36Sopenharmony_ci * @MODE_VBLANK_WIDE: vertical blanking too wide
7662306a36Sopenharmony_ci * @MODE_PANEL: exceeds panel dimensions
7762306a36Sopenharmony_ci * @MODE_INTERLACE_WIDTH: width too large for interlaced mode
7862306a36Sopenharmony_ci * @MODE_ONE_WIDTH: only one width is supported
7962306a36Sopenharmony_ci * @MODE_ONE_HEIGHT: only one height is supported
8062306a36Sopenharmony_ci * @MODE_ONE_SIZE: only one resolution is supported
8162306a36Sopenharmony_ci * @MODE_NO_REDUCED: monitor doesn't accept reduced blanking
8262306a36Sopenharmony_ci * @MODE_NO_STEREO: stereo modes not supported
8362306a36Sopenharmony_ci * @MODE_NO_420: ycbcr 420 modes not supported
8462306a36Sopenharmony_ci * @MODE_STALE: mode has become stale
8562306a36Sopenharmony_ci * @MODE_BAD: unspecified reason
8662306a36Sopenharmony_ci * @MODE_ERROR: error condition
8762306a36Sopenharmony_ci *
8862306a36Sopenharmony_ci * This enum is used to filter out modes not supported by the driver/hardware
8962306a36Sopenharmony_ci * combination.
9062306a36Sopenharmony_ci */
9162306a36Sopenharmony_cienum drm_mode_status {
9262306a36Sopenharmony_ci	MODE_OK = 0,
9362306a36Sopenharmony_ci	MODE_HSYNC,
9462306a36Sopenharmony_ci	MODE_VSYNC,
9562306a36Sopenharmony_ci	MODE_H_ILLEGAL,
9662306a36Sopenharmony_ci	MODE_V_ILLEGAL,
9762306a36Sopenharmony_ci	MODE_BAD_WIDTH,
9862306a36Sopenharmony_ci	MODE_NOMODE,
9962306a36Sopenharmony_ci	MODE_NO_INTERLACE,
10062306a36Sopenharmony_ci	MODE_NO_DBLESCAN,
10162306a36Sopenharmony_ci	MODE_NO_VSCAN,
10262306a36Sopenharmony_ci	MODE_MEM,
10362306a36Sopenharmony_ci	MODE_VIRTUAL_X,
10462306a36Sopenharmony_ci	MODE_VIRTUAL_Y,
10562306a36Sopenharmony_ci	MODE_MEM_VIRT,
10662306a36Sopenharmony_ci	MODE_NOCLOCK,
10762306a36Sopenharmony_ci	MODE_CLOCK_HIGH,
10862306a36Sopenharmony_ci	MODE_CLOCK_LOW,
10962306a36Sopenharmony_ci	MODE_CLOCK_RANGE,
11062306a36Sopenharmony_ci	MODE_BAD_HVALUE,
11162306a36Sopenharmony_ci	MODE_BAD_VVALUE,
11262306a36Sopenharmony_ci	MODE_BAD_VSCAN,
11362306a36Sopenharmony_ci	MODE_HSYNC_NARROW,
11462306a36Sopenharmony_ci	MODE_HSYNC_WIDE,
11562306a36Sopenharmony_ci	MODE_HBLANK_NARROW,
11662306a36Sopenharmony_ci	MODE_HBLANK_WIDE,
11762306a36Sopenharmony_ci	MODE_VSYNC_NARROW,
11862306a36Sopenharmony_ci	MODE_VSYNC_WIDE,
11962306a36Sopenharmony_ci	MODE_VBLANK_NARROW,
12062306a36Sopenharmony_ci	MODE_VBLANK_WIDE,
12162306a36Sopenharmony_ci	MODE_PANEL,
12262306a36Sopenharmony_ci	MODE_INTERLACE_WIDTH,
12362306a36Sopenharmony_ci	MODE_ONE_WIDTH,
12462306a36Sopenharmony_ci	MODE_ONE_HEIGHT,
12562306a36Sopenharmony_ci	MODE_ONE_SIZE,
12662306a36Sopenharmony_ci	MODE_NO_REDUCED,
12762306a36Sopenharmony_ci	MODE_NO_STEREO,
12862306a36Sopenharmony_ci	MODE_NO_420,
12962306a36Sopenharmony_ci	MODE_STALE = -3,
13062306a36Sopenharmony_ci	MODE_BAD = -2,
13162306a36Sopenharmony_ci	MODE_ERROR = -1
13262306a36Sopenharmony_ci};
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
13562306a36Sopenharmony_ci	.name = nm, .status = 0, .type = (t), .clock = (c), \
13662306a36Sopenharmony_ci	.hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
13762306a36Sopenharmony_ci	.htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
13862306a36Sopenharmony_ci	.vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
13962306a36Sopenharmony_ci	.vscan = (vs), .flags = (f)
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci/**
14262306a36Sopenharmony_ci * DRM_MODE_RES_MM - Calculates the display size from resolution and DPI
14362306a36Sopenharmony_ci * @res: The resolution in pixel
14462306a36Sopenharmony_ci * @dpi: The number of dots per inch
14562306a36Sopenharmony_ci */
14662306a36Sopenharmony_ci#define DRM_MODE_RES_MM(res, dpi)	\
14762306a36Sopenharmony_ci	(((res) * 254ul) / ((dpi) * 10ul))
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci#define __DRM_MODE_INIT(pix, hd, vd, hd_mm, vd_mm) \
15062306a36Sopenharmony_ci	.type = DRM_MODE_TYPE_DRIVER, .clock = (pix), \
15162306a36Sopenharmony_ci	.hdisplay = (hd), .hsync_start = (hd), .hsync_end = (hd), \
15262306a36Sopenharmony_ci	.htotal = (hd), .vdisplay = (vd), .vsync_start = (vd), \
15362306a36Sopenharmony_ci	.vsync_end = (vd), .vtotal = (vd), .width_mm = (hd_mm), \
15462306a36Sopenharmony_ci	.height_mm = (vd_mm)
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci/**
15762306a36Sopenharmony_ci * DRM_MODE_INIT - Initialize display mode
15862306a36Sopenharmony_ci * @hz: Vertical refresh rate in Hertz
15962306a36Sopenharmony_ci * @hd: Horizontal resolution, width
16062306a36Sopenharmony_ci * @vd: Vertical resolution, height
16162306a36Sopenharmony_ci * @hd_mm: Display width in millimeters
16262306a36Sopenharmony_ci * @vd_mm: Display height in millimeters
16362306a36Sopenharmony_ci *
16462306a36Sopenharmony_ci * This macro initializes a &drm_display_mode that contains information about
16562306a36Sopenharmony_ci * refresh rate, resolution and physical size.
16662306a36Sopenharmony_ci */
16762306a36Sopenharmony_ci#define DRM_MODE_INIT(hz, hd, vd, hd_mm, vd_mm) \
16862306a36Sopenharmony_ci	__DRM_MODE_INIT((hd) * (vd) * (hz) / 1000 /* kHz */, hd, vd, hd_mm, vd_mm)
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/**
17162306a36Sopenharmony_ci * DRM_SIMPLE_MODE - Simple display mode
17262306a36Sopenharmony_ci * @hd: Horizontal resolution, width
17362306a36Sopenharmony_ci * @vd: Vertical resolution, height
17462306a36Sopenharmony_ci * @hd_mm: Display width in millimeters
17562306a36Sopenharmony_ci * @vd_mm: Display height in millimeters
17662306a36Sopenharmony_ci *
17762306a36Sopenharmony_ci * This macro initializes a &drm_display_mode that only contains info about
17862306a36Sopenharmony_ci * resolution and physical size.
17962306a36Sopenharmony_ci */
18062306a36Sopenharmony_ci#define DRM_SIMPLE_MODE(hd, vd, hd_mm, vd_mm) \
18162306a36Sopenharmony_ci	__DRM_MODE_INIT(1 /* pass validation */, hd, vd, hd_mm, vd_mm)
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci#define CRTC_INTERLACE_HALVE_V	(1 << 0) /* halve V values for interlacing */
18462306a36Sopenharmony_ci#define CRTC_STEREO_DOUBLE	(1 << 1) /* adjust timings for stereo modes */
18562306a36Sopenharmony_ci#define CRTC_NO_DBLSCAN		(1 << 2) /* don't adjust doublescan */
18662306a36Sopenharmony_ci#define CRTC_NO_VSCAN		(1 << 3) /* don't adjust doublescan */
18762306a36Sopenharmony_ci#define CRTC_STEREO_DOUBLE_ONLY	(CRTC_STEREO_DOUBLE | CRTC_NO_DBLSCAN | CRTC_NO_VSCAN)
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci#define DRM_MODE_FLAG_3D_MAX	DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci#define DRM_MODE_MATCH_TIMINGS (1 << 0)
19262306a36Sopenharmony_ci#define DRM_MODE_MATCH_CLOCK (1 << 1)
19362306a36Sopenharmony_ci#define DRM_MODE_MATCH_FLAGS (1 << 2)
19462306a36Sopenharmony_ci#define DRM_MODE_MATCH_3D_FLAGS (1 << 3)
19562306a36Sopenharmony_ci#define DRM_MODE_MATCH_ASPECT_RATIO (1 << 4)
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci/**
19862306a36Sopenharmony_ci * struct drm_display_mode - DRM kernel-internal display mode structure
19962306a36Sopenharmony_ci * @hdisplay: horizontal display size
20062306a36Sopenharmony_ci * @hsync_start: horizontal sync start
20162306a36Sopenharmony_ci * @hsync_end: horizontal sync end
20262306a36Sopenharmony_ci * @htotal: horizontal total size
20362306a36Sopenharmony_ci * @hskew: horizontal skew?!
20462306a36Sopenharmony_ci * @vdisplay: vertical display size
20562306a36Sopenharmony_ci * @vsync_start: vertical sync start
20662306a36Sopenharmony_ci * @vsync_end: vertical sync end
20762306a36Sopenharmony_ci * @vtotal: vertical total size
20862306a36Sopenharmony_ci * @vscan: vertical scan?!
20962306a36Sopenharmony_ci * @crtc_hdisplay: hardware mode horizontal display size
21062306a36Sopenharmony_ci * @crtc_hblank_start: hardware mode horizontal blank start
21162306a36Sopenharmony_ci * @crtc_hblank_end: hardware mode horizontal blank end
21262306a36Sopenharmony_ci * @crtc_hsync_start: hardware mode horizontal sync start
21362306a36Sopenharmony_ci * @crtc_hsync_end: hardware mode horizontal sync end
21462306a36Sopenharmony_ci * @crtc_htotal: hardware mode horizontal total size
21562306a36Sopenharmony_ci * @crtc_hskew: hardware mode horizontal skew?!
21662306a36Sopenharmony_ci * @crtc_vdisplay: hardware mode vertical display size
21762306a36Sopenharmony_ci * @crtc_vblank_start: hardware mode vertical blank start
21862306a36Sopenharmony_ci * @crtc_vblank_end: hardware mode vertical blank end
21962306a36Sopenharmony_ci * @crtc_vsync_start: hardware mode vertical sync start
22062306a36Sopenharmony_ci * @crtc_vsync_end: hardware mode vertical sync end
22162306a36Sopenharmony_ci * @crtc_vtotal: hardware mode vertical total size
22262306a36Sopenharmony_ci *
22362306a36Sopenharmony_ci * This is the kernel API display mode information structure. For the
22462306a36Sopenharmony_ci * user-space version see struct drm_mode_modeinfo.
22562306a36Sopenharmony_ci *
22662306a36Sopenharmony_ci * The horizontal and vertical timings are defined per the following diagram.
22762306a36Sopenharmony_ci *
22862306a36Sopenharmony_ci * ::
22962306a36Sopenharmony_ci *
23062306a36Sopenharmony_ci *
23162306a36Sopenharmony_ci *               Active                 Front           Sync           Back
23262306a36Sopenharmony_ci *              Region                 Porch                          Porch
23362306a36Sopenharmony_ci *     <-----------------------><----------------><-------------><-------------->
23462306a36Sopenharmony_ci *       //////////////////////|
23562306a36Sopenharmony_ci *      ////////////////////// |
23662306a36Sopenharmony_ci *     //////////////////////  |..................               ................
23762306a36Sopenharmony_ci *                                                _______________
23862306a36Sopenharmony_ci *     <----- [hv]display ----->
23962306a36Sopenharmony_ci *     <------------- [hv]sync_start ------------>
24062306a36Sopenharmony_ci *     <--------------------- [hv]sync_end --------------------->
24162306a36Sopenharmony_ci *     <-------------------------------- [hv]total ----------------------------->*
24262306a36Sopenharmony_ci *
24362306a36Sopenharmony_ci * This structure contains two copies of timings. First are the plain timings,
24462306a36Sopenharmony_ci * which specify the logical mode, as it would be for a progressive 1:1 scanout
24562306a36Sopenharmony_ci * at the refresh rate userspace can observe through vblank timestamps. Then
24662306a36Sopenharmony_ci * there's the hardware timings, which are corrected for interlacing,
24762306a36Sopenharmony_ci * double-clocking and similar things. They are provided as a convenience, and
24862306a36Sopenharmony_ci * can be appropriately computed using drm_mode_set_crtcinfo().
24962306a36Sopenharmony_ci *
25062306a36Sopenharmony_ci * For printing you can use %DRM_MODE_FMT and DRM_MODE_ARG().
25162306a36Sopenharmony_ci */
25262306a36Sopenharmony_cistruct drm_display_mode {
25362306a36Sopenharmony_ci	/**
25462306a36Sopenharmony_ci	 * @clock:
25562306a36Sopenharmony_ci	 *
25662306a36Sopenharmony_ci	 * Pixel clock in kHz.
25762306a36Sopenharmony_ci	 */
25862306a36Sopenharmony_ci	int clock;		/* in kHz */
25962306a36Sopenharmony_ci	u16 hdisplay;
26062306a36Sopenharmony_ci	u16 hsync_start;
26162306a36Sopenharmony_ci	u16 hsync_end;
26262306a36Sopenharmony_ci	u16 htotal;
26362306a36Sopenharmony_ci	u16 hskew;
26462306a36Sopenharmony_ci	u16 vdisplay;
26562306a36Sopenharmony_ci	u16 vsync_start;
26662306a36Sopenharmony_ci	u16 vsync_end;
26762306a36Sopenharmony_ci	u16 vtotal;
26862306a36Sopenharmony_ci	u16 vscan;
26962306a36Sopenharmony_ci	/**
27062306a36Sopenharmony_ci	 * @flags:
27162306a36Sopenharmony_ci	 *
27262306a36Sopenharmony_ci	 * Sync and timing flags:
27362306a36Sopenharmony_ci	 *
27462306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_PHSYNC: horizontal sync is active high.
27562306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_NHSYNC: horizontal sync is active low.
27662306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_PVSYNC: vertical sync is active high.
27762306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_NVSYNC: vertical sync is active low.
27862306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_INTERLACE: mode is interlaced.
27962306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_DBLSCAN: mode uses doublescan.
28062306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_CSYNC: mode uses composite sync.
28162306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_PCSYNC: composite sync is active high.
28262306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_NCSYNC: composite sync is active low.
28362306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_HSKEW: hskew provided (not used?).
28462306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_BCAST: <deprecated>
28562306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_PIXMUX: <deprecated>
28662306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_DBLCLK: double-clocked mode.
28762306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_CLKDIV2: half-clocked mode.
28862306a36Sopenharmony_ci	 *
28962306a36Sopenharmony_ci	 * Additionally there's flags to specify how 3D modes are packed:
29062306a36Sopenharmony_ci	 *
29162306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_NONE: normal, non-3D mode.
29262306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_FRAME_PACKING: 2 full frames for left and right.
29362306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: interleaved like fields.
29462306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: interleaved lines.
29562306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: side-by-side full frames.
29662306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_L_DEPTH: ?
29762306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: ?
29862306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: frame split into top and bottom
29962306a36Sopenharmony_ci	 *    parts.
30062306a36Sopenharmony_ci	 *  - DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: frame split into left and
30162306a36Sopenharmony_ci	 *    right parts.
30262306a36Sopenharmony_ci	 */
30362306a36Sopenharmony_ci	u32 flags;
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	/**
30662306a36Sopenharmony_ci	 * @crtc_clock:
30762306a36Sopenharmony_ci	 *
30862306a36Sopenharmony_ci	 * Actual pixel or dot clock in the hardware. This differs from the
30962306a36Sopenharmony_ci	 * logical @clock when e.g. using interlacing, double-clocking, stereo
31062306a36Sopenharmony_ci	 * modes or other fancy stuff that changes the timings and signals
31162306a36Sopenharmony_ci	 * actually sent over the wire.
31262306a36Sopenharmony_ci	 *
31362306a36Sopenharmony_ci	 * This is again in kHz.
31462306a36Sopenharmony_ci	 *
31562306a36Sopenharmony_ci	 * Note that with digital outputs like HDMI or DP there's usually a
31662306a36Sopenharmony_ci	 * massive confusion between the dot clock and the signal clock at the
31762306a36Sopenharmony_ci	 * bit encoding level. Especially when a 8b/10b encoding is used and the
31862306a36Sopenharmony_ci	 * difference is exactly a factor of 10.
31962306a36Sopenharmony_ci	 */
32062306a36Sopenharmony_ci	int crtc_clock;
32162306a36Sopenharmony_ci	u16 crtc_hdisplay;
32262306a36Sopenharmony_ci	u16 crtc_hblank_start;
32362306a36Sopenharmony_ci	u16 crtc_hblank_end;
32462306a36Sopenharmony_ci	u16 crtc_hsync_start;
32562306a36Sopenharmony_ci	u16 crtc_hsync_end;
32662306a36Sopenharmony_ci	u16 crtc_htotal;
32762306a36Sopenharmony_ci	u16 crtc_hskew;
32862306a36Sopenharmony_ci	u16 crtc_vdisplay;
32962306a36Sopenharmony_ci	u16 crtc_vblank_start;
33062306a36Sopenharmony_ci	u16 crtc_vblank_end;
33162306a36Sopenharmony_ci	u16 crtc_vsync_start;
33262306a36Sopenharmony_ci	u16 crtc_vsync_end;
33362306a36Sopenharmony_ci	u16 crtc_vtotal;
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	/**
33662306a36Sopenharmony_ci	 * @width_mm:
33762306a36Sopenharmony_ci	 *
33862306a36Sopenharmony_ci	 * Addressable size of the output in mm, projectors should set this to
33962306a36Sopenharmony_ci	 * 0.
34062306a36Sopenharmony_ci	 */
34162306a36Sopenharmony_ci	u16 width_mm;
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	/**
34462306a36Sopenharmony_ci	 * @height_mm:
34562306a36Sopenharmony_ci	 *
34662306a36Sopenharmony_ci	 * Addressable size of the output in mm, projectors should set this to
34762306a36Sopenharmony_ci	 * 0.
34862306a36Sopenharmony_ci	 */
34962306a36Sopenharmony_ci	u16 height_mm;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	/**
35262306a36Sopenharmony_ci	 * @type:
35362306a36Sopenharmony_ci	 *
35462306a36Sopenharmony_ci	 * A bitmask of flags, mostly about the source of a mode. Possible flags
35562306a36Sopenharmony_ci	 * are:
35662306a36Sopenharmony_ci	 *
35762306a36Sopenharmony_ci	 *  - DRM_MODE_TYPE_PREFERRED: Preferred mode, usually the native
35862306a36Sopenharmony_ci	 *    resolution of an LCD panel. There should only be one preferred
35962306a36Sopenharmony_ci	 *    mode per connector at any given time.
36062306a36Sopenharmony_ci	 *  - DRM_MODE_TYPE_DRIVER: Mode created by the driver, which is all of
36162306a36Sopenharmony_ci	 *    them really. Drivers must set this bit for all modes they create
36262306a36Sopenharmony_ci	 *    and expose to userspace.
36362306a36Sopenharmony_ci	 *  - DRM_MODE_TYPE_USERDEF: Mode defined or selected via the kernel
36462306a36Sopenharmony_ci	 *    command line.
36562306a36Sopenharmony_ci	 *
36662306a36Sopenharmony_ci	 * Plus a big list of flags which shouldn't be used at all, but are
36762306a36Sopenharmony_ci	 * still around since these flags are also used in the userspace ABI.
36862306a36Sopenharmony_ci	 * We no longer accept modes with these types though:
36962306a36Sopenharmony_ci	 *
37062306a36Sopenharmony_ci	 *  - DRM_MODE_TYPE_BUILTIN: Meant for hard-coded modes, unused.
37162306a36Sopenharmony_ci	 *    Use DRM_MODE_TYPE_DRIVER instead.
37262306a36Sopenharmony_ci	 *  - DRM_MODE_TYPE_DEFAULT: Again a leftover, use
37362306a36Sopenharmony_ci	 *    DRM_MODE_TYPE_PREFERRED instead.
37462306a36Sopenharmony_ci	 *  - DRM_MODE_TYPE_CLOCK_C and DRM_MODE_TYPE_CRTC_C: Define leftovers
37562306a36Sopenharmony_ci	 *    which are stuck around for hysterical raisins only. No one has an
37662306a36Sopenharmony_ci	 *    idea what they were meant for. Don't use.
37762306a36Sopenharmony_ci	 */
37862306a36Sopenharmony_ci	u8 type;
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	/**
38162306a36Sopenharmony_ci	 * @expose_to_userspace:
38262306a36Sopenharmony_ci	 *
38362306a36Sopenharmony_ci	 * Indicates whether the mode is to be exposed to the userspace.
38462306a36Sopenharmony_ci	 * This is to maintain a set of exposed modes while preparing
38562306a36Sopenharmony_ci	 * user-mode's list in drm_mode_getconnector ioctl. The purpose of
38662306a36Sopenharmony_ci	 * this only lies in the ioctl function, and is not to be used
38762306a36Sopenharmony_ci	 * outside the function.
38862306a36Sopenharmony_ci	 */
38962306a36Sopenharmony_ci	bool expose_to_userspace;
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	/**
39262306a36Sopenharmony_ci	 * @head:
39362306a36Sopenharmony_ci	 *
39462306a36Sopenharmony_ci	 * struct list_head for mode lists.
39562306a36Sopenharmony_ci	 */
39662306a36Sopenharmony_ci	struct list_head head;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	/**
39962306a36Sopenharmony_ci	 * @name:
40062306a36Sopenharmony_ci	 *
40162306a36Sopenharmony_ci	 * Human-readable name of the mode, filled out with drm_mode_set_name().
40262306a36Sopenharmony_ci	 */
40362306a36Sopenharmony_ci	char name[DRM_DISPLAY_MODE_LEN];
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	/**
40662306a36Sopenharmony_ci	 * @status:
40762306a36Sopenharmony_ci	 *
40862306a36Sopenharmony_ci	 * Status of the mode, used to filter out modes not supported by the
40962306a36Sopenharmony_ci	 * hardware. See enum &drm_mode_status.
41062306a36Sopenharmony_ci	 */
41162306a36Sopenharmony_ci	enum drm_mode_status status;
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	/**
41462306a36Sopenharmony_ci	 * @picture_aspect_ratio:
41562306a36Sopenharmony_ci	 *
41662306a36Sopenharmony_ci	 * Field for setting the HDMI picture aspect ratio of a mode.
41762306a36Sopenharmony_ci	 */
41862306a36Sopenharmony_ci	enum hdmi_picture_aspect picture_aspect_ratio;
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci};
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci/**
42362306a36Sopenharmony_ci * DRM_MODE_FMT - printf string for &struct drm_display_mode
42462306a36Sopenharmony_ci */
42562306a36Sopenharmony_ci#define DRM_MODE_FMT    "\"%s\": %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x"
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_ci/**
42862306a36Sopenharmony_ci * DRM_MODE_ARG - printf arguments for &struct drm_display_mode
42962306a36Sopenharmony_ci * @m: display mode
43062306a36Sopenharmony_ci */
43162306a36Sopenharmony_ci#define DRM_MODE_ARG(m) \
43262306a36Sopenharmony_ci	(m)->name, drm_mode_vrefresh(m), (m)->clock, \
43362306a36Sopenharmony_ci	(m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \
43462306a36Sopenharmony_ci	(m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \
43562306a36Sopenharmony_ci	(m)->type, (m)->flags
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci#define obj_to_mode(x) container_of(x, struct drm_display_mode, base)
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci/**
44062306a36Sopenharmony_ci * drm_mode_is_stereo - check for stereo mode flags
44162306a36Sopenharmony_ci * @mode: drm_display_mode to check
44262306a36Sopenharmony_ci *
44362306a36Sopenharmony_ci * Returns:
44462306a36Sopenharmony_ci * True if the mode is one of the stereo modes (like side-by-side), false if
44562306a36Sopenharmony_ci * not.
44662306a36Sopenharmony_ci */
44762306a36Sopenharmony_cistatic inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
44862306a36Sopenharmony_ci{
44962306a36Sopenharmony_ci	return mode->flags & DRM_MODE_FLAG_3D_MASK;
45062306a36Sopenharmony_ci}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_cistruct drm_connector;
45362306a36Sopenharmony_cistruct drm_cmdline_mode;
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_cistruct drm_display_mode *drm_mode_create(struct drm_device *dev);
45662306a36Sopenharmony_civoid drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
45762306a36Sopenharmony_civoid drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
45862306a36Sopenharmony_ci			       const struct drm_display_mode *in);
45962306a36Sopenharmony_ciint drm_mode_convert_umode(struct drm_device *dev,
46062306a36Sopenharmony_ci			   struct drm_display_mode *out,
46162306a36Sopenharmony_ci			   const struct drm_mode_modeinfo *in);
46262306a36Sopenharmony_civoid drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
46362306a36Sopenharmony_civoid drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
46462306a36Sopenharmony_cibool drm_mode_is_420_only(const struct drm_display_info *display,
46562306a36Sopenharmony_ci			  const struct drm_display_mode *mode);
46662306a36Sopenharmony_cibool drm_mode_is_420_also(const struct drm_display_info *display,
46762306a36Sopenharmony_ci			  const struct drm_display_mode *mode);
46862306a36Sopenharmony_cibool drm_mode_is_420(const struct drm_display_info *display,
46962306a36Sopenharmony_ci		     const struct drm_display_mode *mode);
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_cistruct drm_display_mode *drm_analog_tv_mode(struct drm_device *dev,
47262306a36Sopenharmony_ci					    enum drm_connector_tv_mode mode,
47362306a36Sopenharmony_ci					    unsigned long pixel_clock_hz,
47462306a36Sopenharmony_ci					    unsigned int hdisplay,
47562306a36Sopenharmony_ci					    unsigned int vdisplay,
47662306a36Sopenharmony_ci					    bool interlace);
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_cistatic inline struct drm_display_mode *drm_mode_analog_ntsc_480i(struct drm_device *dev)
47962306a36Sopenharmony_ci{
48062306a36Sopenharmony_ci	return drm_analog_tv_mode(dev, DRM_MODE_TV_MODE_NTSC, 13500000, 720, 480, true);
48162306a36Sopenharmony_ci}
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_cistatic inline struct drm_display_mode *drm_mode_analog_pal_576i(struct drm_device *dev)
48462306a36Sopenharmony_ci{
48562306a36Sopenharmony_ci	return drm_analog_tv_mode(dev, DRM_MODE_TV_MODE_PAL, 13500000, 720, 576, true);
48662306a36Sopenharmony_ci}
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_cistruct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
48962306a36Sopenharmony_ci				      int hdisplay, int vdisplay, int vrefresh,
49062306a36Sopenharmony_ci				      bool reduced, bool interlaced,
49162306a36Sopenharmony_ci				      bool margins);
49262306a36Sopenharmony_cistruct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
49362306a36Sopenharmony_ci				      int hdisplay, int vdisplay, int vrefresh,
49462306a36Sopenharmony_ci				      bool interlaced, int margins);
49562306a36Sopenharmony_cistruct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev,
49662306a36Sopenharmony_ci					      int hdisplay, int vdisplay,
49762306a36Sopenharmony_ci					      int vrefresh, bool interlaced,
49862306a36Sopenharmony_ci					      int margins,
49962306a36Sopenharmony_ci					      int GTF_M, int GTF_2C,
50062306a36Sopenharmony_ci					      int GTF_K, int GTF_2J);
50162306a36Sopenharmony_civoid drm_display_mode_from_videomode(const struct videomode *vm,
50262306a36Sopenharmony_ci				     struct drm_display_mode *dmode);
50362306a36Sopenharmony_civoid drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
50462306a36Sopenharmony_ci				   struct videomode *vm);
50562306a36Sopenharmony_civoid drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci#if defined(CONFIG_OF)
50862306a36Sopenharmony_ciint of_get_drm_display_mode(struct device_node *np,
50962306a36Sopenharmony_ci			    struct drm_display_mode *dmode, u32 *bus_flags,
51062306a36Sopenharmony_ci			    int index);
51162306a36Sopenharmony_ciint of_get_drm_panel_display_mode(struct device_node *np,
51262306a36Sopenharmony_ci				  struct drm_display_mode *dmode, u32 *bus_flags);
51362306a36Sopenharmony_ci#else
51462306a36Sopenharmony_cistatic inline int of_get_drm_display_mode(struct device_node *np,
51562306a36Sopenharmony_ci					  struct drm_display_mode *dmode,
51662306a36Sopenharmony_ci					  u32 *bus_flags, int index)
51762306a36Sopenharmony_ci{
51862306a36Sopenharmony_ci	return -EINVAL;
51962306a36Sopenharmony_ci}
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_cistatic inline int of_get_drm_panel_display_mode(struct device_node *np,
52262306a36Sopenharmony_ci						struct drm_display_mode *dmode, u32 *bus_flags)
52362306a36Sopenharmony_ci{
52462306a36Sopenharmony_ci	return -EINVAL;
52562306a36Sopenharmony_ci}
52662306a36Sopenharmony_ci#endif
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_civoid drm_mode_set_name(struct drm_display_mode *mode);
52962306a36Sopenharmony_ciint drm_mode_vrefresh(const struct drm_display_mode *mode);
53062306a36Sopenharmony_civoid drm_mode_get_hv_timing(const struct drm_display_mode *mode,
53162306a36Sopenharmony_ci			    int *hdisplay, int *vdisplay);
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_civoid drm_mode_set_crtcinfo(struct drm_display_mode *p,
53462306a36Sopenharmony_ci			   int adjust_flags);
53562306a36Sopenharmony_civoid drm_mode_copy(struct drm_display_mode *dst,
53662306a36Sopenharmony_ci		   const struct drm_display_mode *src);
53762306a36Sopenharmony_civoid drm_mode_init(struct drm_display_mode *dst,
53862306a36Sopenharmony_ci		   const struct drm_display_mode *src);
53962306a36Sopenharmony_cistruct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
54062306a36Sopenharmony_ci					    const struct drm_display_mode *mode);
54162306a36Sopenharmony_cibool drm_mode_match(const struct drm_display_mode *mode1,
54262306a36Sopenharmony_ci		    const struct drm_display_mode *mode2,
54362306a36Sopenharmony_ci		    unsigned int match_flags);
54462306a36Sopenharmony_cibool drm_mode_equal(const struct drm_display_mode *mode1,
54562306a36Sopenharmony_ci		    const struct drm_display_mode *mode2);
54662306a36Sopenharmony_cibool drm_mode_equal_no_clocks(const struct drm_display_mode *mode1,
54762306a36Sopenharmony_ci			      const struct drm_display_mode *mode2);
54862306a36Sopenharmony_cibool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
54962306a36Sopenharmony_ci					const struct drm_display_mode *mode2);
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci/* for use by the crtc helper probe functions */
55262306a36Sopenharmony_cienum drm_mode_status drm_mode_validate_driver(struct drm_device *dev,
55362306a36Sopenharmony_ci					      const struct drm_display_mode *mode);
55462306a36Sopenharmony_cienum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode,
55562306a36Sopenharmony_ci					    int maxX, int maxY);
55662306a36Sopenharmony_cienum drm_mode_status
55762306a36Sopenharmony_cidrm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
55862306a36Sopenharmony_ci			   struct drm_connector *connector);
55962306a36Sopenharmony_civoid drm_mode_prune_invalid(struct drm_device *dev,
56062306a36Sopenharmony_ci			    struct list_head *mode_list, bool verbose);
56162306a36Sopenharmony_civoid drm_mode_sort(struct list_head *mode_list);
56262306a36Sopenharmony_civoid drm_connector_list_update(struct drm_connector *connector);
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_ci/* parsing cmdline modes */
56562306a36Sopenharmony_cibool
56662306a36Sopenharmony_cidrm_mode_parse_command_line_for_connector(const char *mode_option,
56762306a36Sopenharmony_ci					  const struct drm_connector *connector,
56862306a36Sopenharmony_ci					  struct drm_cmdline_mode *mode);
56962306a36Sopenharmony_cistruct drm_display_mode *
57062306a36Sopenharmony_cidrm_mode_create_from_cmdline_mode(struct drm_device *dev,
57162306a36Sopenharmony_ci				  struct drm_cmdline_mode *cmd);
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci#endif /* __DRM_MODES_H__ */
574