summaryrefslogtreecommitdiffstats
path: root/include/drm
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/drmP.h29
-rw-r--r--include/drm/drm_crtc.h174
-rw-r--r--include/drm/drm_crtc_helper.h6
-rw-r--r--include/drm/drm_mm.h154
-rw-r--r--include/drm/drm_modes.h237
5 files changed, 372 insertions, 228 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 538079030be..319ec1eb037 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1056,21 +1056,6 @@ struct drm_minor {
struct drm_mode_group mode_group;
};
-/* mode specified on the command line */
-struct drm_cmdline_mode {
- bool specified;
- bool refresh_specified;
- bool bpp_specified;
- int xres, yres;
- int bpp;
- int refresh;
- bool rb;
- bool interlace;
- bool cvt;
- bool margins;
- enum drm_connector_force force;
-};
-
struct drm_pending_vblank_event {
struct drm_pending_event base;
@@ -1417,20 +1402,6 @@ extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
extern void drm_calc_timestamping_constants(struct drm_crtc *crtc,
const struct drm_display_mode *mode);
-extern bool
-drm_mode_parse_command_line_for_connector(const char *mode_option,
- struct drm_connector *connector,
- struct drm_cmdline_mode *mode);
-
-extern struct drm_display_mode *
-drm_mode_create_from_cmdline_mode(struct drm_device *dev,
- struct drm_cmdline_mode *cmd);
-
-extern int drm_display_mode_from_videomode(const struct videomode *vm,
- struct drm_display_mode *dmode);
-extern int of_get_drm_display_mode(struct device_node *np,
- struct drm_display_mode *dmode,
- int index);
/* Modesetting support */
extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index f7646548660..27f828c9d7f 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -32,7 +32,6 @@
#include <linux/fb.h>
#include <linux/hdmi.h>
#include <drm/drm_mode.h>
-
#include <drm/drm_fourcc.h>
struct drm_device;
@@ -65,130 +64,14 @@ struct drm_object_properties {
uint64_t values[DRM_OBJECT_MAX_PROPERTY];
};
-/*
- * Note on terminology: here, for brevity and convenience, we refer to connector
- * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
- * DVI, etc. And 'screen' refers to the whole of the visible display, which
- * may span multiple monitors (and therefore multiple CRTC and connector
- * structures).
- */
-
-enum drm_mode_status {
- MODE_OK = 0, /* Mode OK */
- MODE_HSYNC, /* hsync out of range */
- MODE_VSYNC, /* vsync out of range */
- MODE_H_ILLEGAL, /* mode has illegal horizontal timings */
- MODE_V_ILLEGAL, /* mode has illegal horizontal timings */
- MODE_BAD_WIDTH, /* requires an unsupported linepitch */
- MODE_NOMODE, /* no mode with a matching name */
- MODE_NO_INTERLACE, /* interlaced mode not supported */
- MODE_NO_DBLESCAN, /* doublescan mode not supported */
- MODE_NO_VSCAN, /* multiscan mode not supported */
- MODE_MEM, /* insufficient video memory */
- MODE_VIRTUAL_X, /* mode width too large for specified virtual size */
- MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */
- MODE_MEM_VIRT, /* insufficient video memory given virtual size */
- MODE_NOCLOCK, /* no fixed clock available */
- MODE_CLOCK_HIGH, /* clock required is too high */
- MODE_CLOCK_LOW, /* clock required is too low */
- MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
- MODE_BAD_HVALUE, /* horizontal timing was out of range */
- MODE_BAD_VVALUE, /* vertical timing was out of range */
- MODE_BAD_VSCAN, /* VScan value out of range */
- MODE_HSYNC_NARROW, /* horizontal sync too narrow */
- MODE_HSYNC_WIDE, /* horizontal sync too wide */
- MODE_HBLANK_NARROW, /* horizontal blanking too narrow */
- MODE_HBLANK_WIDE, /* horizontal blanking too wide */
- MODE_VSYNC_NARROW, /* vertical sync too narrow */
- MODE_VSYNC_WIDE, /* vertical sync too wide */
- MODE_VBLANK_NARROW, /* vertical blanking too narrow */
- MODE_VBLANK_WIDE, /* vertical blanking too wide */
- MODE_PANEL, /* exceeds panel dimensions */
- MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
- MODE_ONE_WIDTH, /* only one width is supported */
- MODE_ONE_HEIGHT, /* only one height is supported */
- MODE_ONE_SIZE, /* only one resolution is supported */
- MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
- MODE_NO_STEREO, /* stereo modes not supported */
- MODE_UNVERIFIED = -3, /* mode needs to reverified */
- MODE_BAD = -2, /* unspecified reason */
- MODE_ERROR = -1 /* error condition */
-};
-
-#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
- DRM_MODE_TYPE_CRTC_C)
-
-#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
- .name = nm, .status = 0, .type = (t), .clock = (c), \
- .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
- .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
- .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
- .vscan = (vs), .flags = (f), \
- .base.type = DRM_MODE_OBJECT_MODE
-
-#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */
-#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
-
-#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
-
-struct drm_display_mode {
- /* Header */
- struct list_head head;
- struct drm_mode_object base;
-
- char name[DRM_DISPLAY_MODE_LEN];
-
- enum drm_mode_status status;
- unsigned int type;
-
- /* Proposed mode values */
- int clock; /* in kHz */
- int hdisplay;
- int hsync_start;
- int hsync_end;
- int htotal;
- int hskew;
- int vdisplay;
- int vsync_start;
- int vsync_end;
- int vtotal;
- int vscan;
- unsigned int flags;
-
- /* Addressable image size (may be 0 for projectors, etc.) */
- int width_mm;
- int height_mm;
-
- /* Actual mode we give to hw */
- int crtc_clock; /* in KHz */
- int crtc_hdisplay;
- int crtc_hblank_start;
- int crtc_hblank_end;
- int crtc_hsync_start;
- int crtc_hsync_end;
- int crtc_htotal;
- int crtc_hskew;
- int crtc_vdisplay;
- int crtc_vblank_start;
- int crtc_vblank_end;
- int crtc_vsync_start;
- int crtc_vsync_end;
- int crtc_vtotal;
-
- /* Driver private mode info */
- int private_size;
- int *private;
- int private_flags;
-
- int vrefresh; /* in Hz */
- int hsync; /* in kHz */
- enum hdmi_picture_aspect picture_aspect_ratio;
+enum drm_connector_force {
+ DRM_FORCE_UNSPECIFIED,
+ DRM_FORCE_OFF,
+ DRM_FORCE_ON, /* force on analog part normally */
+ DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
};
-static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
-{
- return mode->flags & DRM_MODE_FLAG_3D_MASK;
-}
+#include <drm/drm_modes.h>
enum drm_connector_status {
connector_status_connected = 1,
@@ -540,13 +423,6 @@ struct drm_encoder {
void *helper_private;
};
-enum drm_connector_force {
- DRM_FORCE_UNSPECIFIED,
- DRM_FORCE_OFF,
- DRM_FORCE_ON, /* force on analog part normally */
- DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
-};
-
/* should we poll this connector for connects and disconnects */
/* hot plug detectable */
#define DRM_CONNECTOR_POLL_HPD (1 << 0)
@@ -1007,34 +883,10 @@ extern struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter);
extern struct edid *drm_edid_duplicate(const struct edid *edid);
extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
-extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
-extern void drm_mode_copy(struct drm_display_mode *dst, const struct drm_display_mode *src);
-extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
- const struct drm_display_mode *mode);
-extern void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
extern void drm_mode_config_init(struct drm_device *dev);
extern void drm_mode_config_reset(struct drm_device *dev);
extern void drm_mode_config_cleanup(struct drm_device *dev);
-extern void drm_mode_set_name(struct drm_display_mode *mode);
-extern bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2);
-extern bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2);
-extern int drm_mode_width(const struct drm_display_mode *mode);
-extern int drm_mode_height(const struct drm_display_mode *mode);
-
-/* for us by fb module */
-extern struct drm_display_mode *drm_mode_create(struct drm_device *dev);
-extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
-extern void drm_mode_validate_size(struct drm_device *dev,
- struct list_head *mode_list,
- int maxX, int maxY, int maxPitch);
-extern void drm_mode_prune_invalid(struct drm_device *dev,
- struct list_head *mode_list, bool verbose);
-extern void drm_mode_sort(struct list_head *mode_list);
-extern int drm_mode_hsync(const struct drm_display_mode *mode);
-extern int drm_mode_vrefresh(const struct drm_display_mode *mode);
-extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
- int adjust_flags);
-extern void drm_mode_connector_list_update(struct drm_connector *connector);
+
extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
struct edid *edid);
extern int drm_object_property_set_value(struct drm_mode_object *obj,
@@ -1082,8 +934,6 @@ extern const char *drm_get_encoder_name(const struct drm_encoder *encoder);
extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
-extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
- struct drm_encoder *encoder);
extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size);
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
@@ -1138,16 +988,6 @@ extern bool drm_detect_monitor_audio(struct edid *edid);
extern bool drm_rgb_quant_range_selectable(struct edid *edid);
extern int drm_mode_page_flip_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
-extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
- int hdisplay, int vdisplay, int vrefresh,
- bool reduced, bool interlaced, bool margins);
-extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
- int hdisplay, int vdisplay, int vrefresh,
- bool interlaced, int margins);
-extern 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);
extern int drm_add_modes_noedid(struct drm_connector *connector,
int hdisplay, int vdisplay);
extern void drm_set_preferred_mode(struct drm_connector *connector,
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index b1388b5fe7a..0bb34ca2ad2 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -139,8 +139,8 @@ extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
extern void drm_helper_move_panel_connectors_to_head(struct drm_device *);
-extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
- struct drm_mode_fb_cmd2 *mode_cmd);
+extern void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
+ struct drm_mode_fb_cmd2 *mode_cmd);
static inline void drm_crtc_helper_add(struct drm_crtc *crtc,
const struct drm_crtc_helper_funcs *funcs)
@@ -160,7 +160,7 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
connector->helper_private = (void *)funcs;
}
-extern int drm_helper_resume_force_mode(struct drm_device *dev);
+extern void drm_helper_resume_force_mode(struct drm_device *dev);
extern void drm_kms_helper_poll_init(struct drm_device *dev);
extern void drm_kms_helper_poll_fini(struct drm_device *dev);
extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index cba67865d18..8b6981ab3fc 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -85,11 +85,31 @@ struct drm_mm {
unsigned long *start, unsigned long *end);
};
+/**
+ * drm_mm_node_allocated - checks whether a node is allocated
+ * @node: drm_mm_node to check
+ *
+ * Drivers should use this helpers for proper encapusulation of drm_mm
+ * internals.
+ *
+ * Returns:
+ * True if the @node is allocated.
+ */
static inline bool drm_mm_node_allocated(struct drm_mm_node *node)
{
return node->allocated;
}
+/**
+ * drm_mm_initialized - checks whether an allocator is initialized
+ * @mm: drm_mm to check
+ *
+ * Drivers should use this helpers for proper encapusulation of drm_mm
+ * internals.
+ *
+ * Returns:
+ * True if the @mm is initialized.
+ */
static inline bool drm_mm_initialized(struct drm_mm *mm)
{
return mm->hole_stack.next;
@@ -100,6 +120,17 @@ static inline unsigned long __drm_mm_hole_node_start(struct drm_mm_node *hole_no
return hole_node->start + hole_node->size;
}
+/**
+ * drm_mm_hole_node_start - computes the start of the hole following @node
+ * @hole_node: drm_mm_node which implicitly tracks the following hole
+ *
+ * This is useful for driver-sepific debug dumpers. Otherwise drivers should not
+ * inspect holes themselves. Drivers must check first whether a hole indeed
+ * follows by looking at node->hole_follows.
+ *
+ * Returns:
+ * Start of the subsequent hole.
+ */
static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node)
{
BUG_ON(!hole_node->hole_follows);
@@ -112,18 +143,49 @@ static inline unsigned long __drm_mm_hole_node_end(struct drm_mm_node *hole_node
struct drm_mm_node, node_list)->start;
}
+/**
+ * drm_mm_hole_node_end - computes the end of the hole following @node
+ * @hole_node: drm_mm_node which implicitly tracks the following hole
+ *
+ * This is useful for driver-sepific debug dumpers. Otherwise drivers should not
+ * inspect holes themselves. Drivers must check first whether a hole indeed
+ * follows by looking at node->hole_follows.
+ *
+ * Returns:
+ * End of the subsequent hole.
+ */
static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
{
return __drm_mm_hole_node_end(hole_node);
}
+/**
+ * drm_mm_for_each_node - iterator to walk over all allocated nodes
+ * @entry: drm_mm_node structure to assign to in each iteration step
+ * @mm: drm_mm allocator to walk
+ *
+ * This iterator walks over all nodes in the range allocator. It is implemented
+ * with list_for_each, so not save against removal of elements.
+ */
#define drm_mm_for_each_node(entry, mm) list_for_each_entry(entry, \
&(mm)->head_node.node_list, \
node_list)
-/* Note that we need to unroll list_for_each_entry in order to inline
- * setting hole_start and hole_end on each iteration and keep the
- * macro sane.
+/**
+ * drm_mm_for_each_hole - iterator to walk over all holes
+ * @entry: drm_mm_node used internally to track progress
+ * @mm: drm_mm allocator to walk
+ * @hole_start: ulong variable to assign the hole start to on each iteration
+ * @hole_end: ulong variable to assign the hole end to on each iteration
+ *
+ * This iterator walks over all holes in the range allocator. It is implemented
+ * with list_for_each, so not save against removal of elements. @entry is used
+ * internally and will not reflect a real drm_mm_node for the very first hole.
+ * Hence users of this iterator may not access it.
+ *
+ * Implementation Note:
+ * We need to inline list_for_each_entry in order to be able to set hole_start
+ * and hole_end on each iteration while keeping the macro sane.
*/
#define drm_mm_for_each_hole(entry, mm, hole_start, hole_end) \
for (entry = list_entry((mm)->hole_stack.next, struct drm_mm_node, hole_stack); \
@@ -136,14 +198,30 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node)
/*
* Basic range manager support (drm_mm.c)
*/
-extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
-
-extern int drm_mm_insert_node_generic(struct drm_mm *mm,
- struct drm_mm_node *node,
- unsigned long size,
- unsigned alignment,
- unsigned long color,
- enum drm_mm_search_flags flags);
+int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node);
+
+int drm_mm_insert_node_generic(struct drm_mm *mm,
+ struct drm_mm_node *node,
+ unsigned long size,
+ unsigned alignment,
+ unsigned long color,
+ enum drm_mm_search_flags flags);
+/**
+ * drm_mm_insert_node - search for space and insert @node
+ * @mm: drm_mm to allocate from
+ * @node: preallocate node to insert
+ * @size: size of the allocation
+ * @alignment: alignment of the allocation
+ * @flags: flags to fine-tune the allocation
+ *
+ * This is a simplified version of drm_mm_insert_node_generic() with @color set
+ * to 0.
+ *
+ * The preallocated node must be cleared to 0.
+ *
+ * Returns:
+ * 0 on success, -ENOSPC if there's no suitable hole.
+ */
static inline int drm_mm_insert_node(struct drm_mm *mm,
struct drm_mm_node *node,
unsigned long size,
@@ -153,14 +231,32 @@ static inline int drm_mm_insert_node(struct drm_mm *mm,
return drm_mm_insert_node_generic(mm, node, size, alignment, 0, flags);
}
-extern int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
- struct drm_mm_node *node,
- unsigned long size,
- unsigned alignment,
- unsigned long color,
- unsigned long start,
- unsigned long end,
- enum drm_mm_search_flags flags);
+int drm_mm_insert_node_in_range_generic(struct drm_mm *mm,
+ struct drm_mm_node *node,
+ unsigned long size,
+ unsigned alignment,
+ unsigned long color,
+ unsigned long start,
+ unsigned long end,
+ enum drm_mm_search_flags flags);
+/**
+ * drm_mm_insert_node_in_range - ranged search for space and insert @node
+ * @mm: drm_mm to allocate from
+ * @node: preallocate node to insert
+ * @size: size of the allocation
+ * @alignment: alignment of the allocation
+ * @start: start of the allowed range for this node
+ * @end: end of the allowed range for this node
+ * @flags: flags to fine-tune the allocation
+ *
+ * This is a simplified version of drm_mm_insert_node_in_range_generic() with
+ * @color set to 0.
+ *
+ * The preallocated node must be cleared to 0.
+ *
+ * Returns:
+ * 0 on success, -ENOSPC if there's no suitable hole.
+ */
static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
struct drm_mm_node *node,
unsigned long size,
@@ -173,13 +269,13 @@ static inline int drm_mm_insert_node_in_range(struct drm_mm *mm,
0, start, end, flags);
}
-extern void drm_mm_remove_node(struct drm_mm_node *node);
-extern void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
-extern void drm_mm_init(struct drm_mm *mm,
- unsigned long start,
- unsigned long size);
-extern void drm_mm_takedown(struct drm_mm *mm);
-extern int drm_mm_clean(struct drm_mm *mm);
+void drm_mm_remove_node(struct drm_mm_node *node);
+void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new);
+void drm_mm_init(struct drm_mm *mm,
+ unsigned long start,
+ unsigned long size);
+void drm_mm_takedown(struct drm_mm *mm);
+bool drm_mm_clean(struct drm_mm *mm);
void drm_mm_init_scan(struct drm_mm *mm,
unsigned long size,
@@ -191,10 +287,10 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
unsigned long color,
unsigned long start,
unsigned long end);
-int drm_mm_scan_add_block(struct drm_mm_node *node);
-int drm_mm_scan_remove_block(struct drm_mm_node *node);
+bool drm_mm_scan_add_block(struct drm_mm_node *node);
+bool drm_mm_scan_remove_block(struct drm_mm_node *node);
-extern void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
+void drm_mm_debug_table(struct drm_mm *mm, const char *prefix);
#ifdef CONFIG_DEBUG_FS
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm);
#endif
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
new file mode 100644
index 00000000000..2dbbf997666
--- /dev/null
+++ b/include/drm/drm_modes.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright © 2006 Keith Packard
+ * Copyright © 2007-2008 Dave Airlie
+ * Copyright © 2007-2008 Intel Corporation
+ * Jesse Barnes <jesse.barnes@intel.com>
+ * Copyright © 2014 Intel Corporation
+ * Daniel Vetter <daniel.vetter@ffwll.ch>
+ *
+ * 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.
+ */
+#ifndef __DRM_MODES_H__
+#define __DRM_MODES_H__
+
+/*
+ * Note on terminology: here, for brevity and convenience, we refer to connector
+ * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
+ * DVI, etc. And 'screen' refers to the whole of the visible display, which
+ * may span multiple monitors (and therefore multiple CRTC and connector
+ * structures).
+ */
+
+enum drm_mode_status {
+ MODE_OK = 0, /* Mode OK */
+ MODE_HSYNC, /* hsync out of range */
+ MODE_VSYNC, /* vsync out of range */
+ MODE_H_ILLEGAL, /* mode has illegal horizontal timings */
+ MODE_V_ILLEGAL, /* mode has illegal horizontal timings */
+ MODE_BAD_WIDTH, /* requires an unsupported linepitch */
+ MODE_NOMODE, /* no mode with a matching name */
+ MODE_NO_INTERLACE, /* interlaced mode not supported */
+ MODE_NO_DBLESCAN, /* doublescan mode not supported */
+ MODE_NO_VSCAN, /* multiscan mode not supported */
+ MODE_MEM, /* insufficient video memory */
+ MODE_VIRTUAL_X, /* mode width too large for specified virtual size */
+ MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */
+ MODE_MEM_VIRT, /* insufficient video memory given virtual size */
+ MODE_NOCLOCK, /* no fixed clock available */
+ MODE_CLOCK_HIGH, /* clock required is too high */
+ MODE_CLOCK_LOW, /* clock required is too low */
+ MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */
+ MODE_BAD_HVALUE, /* horizontal timing was out of range */
+ MODE_BAD_VVALUE, /* vertical timing was out of range */
+ MODE_BAD_VSCAN, /* VScan value out of range */
+ MODE_HSYNC_NARROW, /* horizontal sync too narrow */
+ MODE_HSYNC_WIDE, /* horizontal sync too wide */
+ MODE_HBLANK_NARROW, /* horizontal blanking too narrow */
+ MODE_HBLANK_WIDE, /* horizontal blanking too wide */
+ MODE_VSYNC_NARROW, /* vertical sync too narrow */
+ MODE_VSYNC_WIDE, /* vertical sync too wide */
+ MODE_VBLANK_NARROW, /* vertical blanking too narrow */
+ MODE_VBLANK_WIDE, /* vertical blanking too wide */
+ MODE_PANEL, /* exceeds panel dimensions */
+ MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */
+ MODE_ONE_WIDTH, /* only one width is supported */
+ MODE_ONE_HEIGHT, /* only one height is supported */
+ MODE_ONE_SIZE, /* only one resolution is supported */
+ MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */
+ MODE_NO_STEREO, /* stereo modes not supported */
+ MODE_UNVERIFIED = -3, /* mode needs to reverified */
+ MODE_BAD = -2, /* unspecified reason */
+ MODE_ERROR = -1 /* error condition */
+};
+
+#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \
+ DRM_MODE_TYPE_CRTC_C)
+
+#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \
+ .name = nm, .status = 0, .type = (t), .clock = (c), \
+ .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \
+ .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \
+ .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \
+ .vscan = (vs), .flags = (f), \
+ .base.type = DRM_MODE_OBJECT_MODE
+
+#define CRTC_INTERLACE_HALVE_V (1 << 0) /* halve V values for interlacing */
+#define CRTC_STEREO_DOUBLE (1 << 1) /* adjust timings for stereo modes */
+
+#define DRM_MODE_FLAG_3D_MAX DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF
+
+struct drm_display_mode {
+ /* Header */
+ struct list_head head;
+ struct drm_mode_object base;
+
+ char name[DRM_DISPLAY_MODE_LEN];
+
+ enum drm_mode_status status;
+ unsigned int type;
+
+ /* Proposed mode values */
+ int clock; /* in kHz */
+ int hdisplay;
+ int hsync_start;
+ int hsync_end;
+ int htotal;
+ int hskew;
+ int vdisplay;
+ int vsync_start;
+ int vsync_end;
+ int vtotal;
+ int vscan;
+ unsigned int flags;
+
+ /* Addressable image size (may be 0 for projectors, etc.) */
+ int width_mm;
+ int height_mm;
+
+ /* Actual mode we give to hw */
+ int crtc_clock; /* in KHz */
+ int crtc_hdisplay;
+ int crtc_hblank_start;
+ int crtc_hblank_end;
+ int crtc_hsync_start;
+ int crtc_hsync_end;
+ int crtc_htotal;
+ int crtc_hskew;
+ int crtc_vdisplay;
+ int crtc_vblank_start;
+ int crtc_vblank_end;
+ int crtc_vsync_start;
+ int crtc_vsync_end;
+ int crtc_vtotal;
+
+ /* Driver private mode info */
+ int *private;
+ int private_flags;
+
+ int vrefresh; /* in Hz */
+ int hsync; /* in kHz */
+ enum hdmi_picture_aspect picture_aspect_ratio;
+};
+
+/* mode specified on the command line */
+struct drm_cmdline_mode {
+ bool specified;
+ bool refresh_specified;
+ bool bpp_specified;
+ int xres, yres;
+ int bpp;
+ int refresh;
+ bool rb;
+ bool interlace;
+ bool cvt;
+ bool margins;
+ enum drm_connector_force force;
+};
+
+/**
+ * drm_mode_is_stereo - check for stereo mode flags
+ * @mode: drm_display_mode to check
+ *
+ * Returns:
+ * True if the mode is one of the stereo modes (like side-by-side), false if
+ * not.
+ */
+static inline bool drm_mode_is_stereo(const struct drm_display_mode *mode)
+{
+ return mode->flags & DRM_MODE_FLAG_3D_MASK;
+}
+
+struct drm_connector;
+struct drm_cmdline_mode;
+
+struct drm_display_mode *drm_mode_create(struct drm_device *dev);
+void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode);
+void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
+void drm_mode_debug_printmodeline(const struct drm_display_mode *mode);
+
+struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
+ int hdisplay, int vdisplay, int vrefresh,
+ bool reduced, bool interlaced,
+ bool margins);
+struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
+ int hdisplay, int vdisplay, int vrefresh,
+ bool interlaced, int margins);
+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);
+void drm_display_mode_from_videomode(const struct videomode *vm,
+ struct drm_display_mode *dmode);
+int of_get_drm_display_mode(struct device_node *np,
+ struct drm_display_mode *dmode,
+ int index);
+
+void drm_mode_set_name(struct drm_display_mode *mode);
+int drm_mode_hsync(const struct drm_display_mode *mode);
+int drm_mode_vrefresh(const struct drm_display_mode *mode);
+
+void drm_mode_set_crtcinfo(struct drm_display_mode *p,
+ int adjust_flags);
+void drm_mode_copy(struct drm_display_mode *dst,
+ const struct drm_display_mode *src);
+struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
+ const struct drm_display_mode *mode);
+bool drm_mode_equal(const struct drm_display_mode *mode1,
+ const struct drm_display_mode *mode2);
+bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
+ const struct drm_display_mode *mode2);
+
+/* for use by the crtc helper probe functions */
+void drm_mode_validate_size(struct drm_device *dev,
+ struct list_head *mode_list,
+ int maxX, int maxY);
+void drm_mode_prune_invalid(struct drm_device *dev,
+ struct list_head *mode_list, bool verbose);
+void drm_mode_sort(struct list_head *mode_list);
+void drm_mode_connector_list_update(struct drm_connector *connector);
+
+/* parsing cmdline modes */
+bool
+drm_mode_parse_command_line_for_connector(const char *mode_option,
+ struct drm_connector *connector,
+ struct drm_cmdline_mode *mode);
+struct drm_display_mode *
+drm_mode_create_from_cmdline_mode(struct drm_device *dev,
+ struct drm_cmdline_mode *cmd);
+
+#endif /* __DRM_MODES_H__ */