summaryrefslogtreecommitdiffstats
path: root/include/drm
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/drmP.h10
-rw-r--r--include/drm/drm_atomic.h95
-rw-r--r--include/drm/drm_blend.h22
-rw-r--r--include/drm/drm_bridge.h42
-rw-r--r--include/drm/drm_color_mgmt.h2
-rw-r--r--include/drm/drm_connector.h23
-rw-r--r--include/drm/drm_crtc.h62
-rw-r--r--include/drm/drm_dp_helper.h166
-rw-r--r--include/drm/drm_dp_mst_helper.h26
-rw-r--r--include/drm/drm_drv.h75
-rw-r--r--include/drm/drm_fb_cma_helper.h4
-rw-r--r--include/drm/drm_gem_cma_helper.h17
-rw-r--r--include/drm/drm_irq.h21
-rw-r--r--include/drm/drm_mem_util.h81
-rw-r--r--include/drm/drm_modeset_helper_vtables.h159
-rw-r--r--include/drm/drm_panel.h2
-rw-r--r--include/drm/drm_prime.h7
-rw-r--r--include/drm/ttm/ttm_bo_driver.h9
-rw-r--r--include/drm/ttm/ttm_execbuf_util.h3
-rw-r--r--include/drm/ttm/ttm_lock.h3
-rw-r--r--include/drm/ttm/ttm_object.h3
21 files changed, 605 insertions, 227 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e1daa4f343cd..b9b5566acfe6 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -70,7 +70,6 @@
#include <drm/drm_fourcc.h>
#include <drm/drm_global.h>
#include <drm/drm_hashtab.h>
-#include <drm/drm_mem_util.h>
#include <drm/drm_mm.h>
#include <drm/drm_os_linux.h>
#include <drm/drm_sarea.h>
@@ -320,15 +319,6 @@ struct pci_controller;
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
-/* Flags and return codes for get_vblank_timestamp() driver function. */
-#define DRM_CALLED_FROM_VBLIRQ 1
-#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
-
-/* get_scanout_position() return flags */
-#define DRM_SCANOUTPOS_VALID (1 << 0)
-#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1)
-#define DRM_SCANOUTPOS_ACCURATE (1 << 2)
-
/**
* DRM device structure. This structure represent a complete card that
* may contain multiple heads.
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 788daf756f48..8645dcdef031 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -155,6 +155,53 @@ struct __drm_connnectors_state {
};
/**
+ * struct drm_private_state_funcs - atomic state functions for private objects
+ *
+ * These hooks are used by atomic helpers to create, swap and destroy states of
+ * private objects. The structure itself is used as a vtable to identify the
+ * associated private object type. Each private object type that needs to be
+ * added to the atomic states is expected to have an implementation of these
+ * hooks and pass a pointer to it's drm_private_state_funcs struct to
+ * drm_atomic_get_private_obj_state().
+ */
+struct drm_private_state_funcs {
+ /**
+ * @duplicate_state:
+ *
+ * Duplicate the current state of the private object and return it. It
+ * is an error to call this before obj->state has been initialized.
+ *
+ * RETURNS:
+ *
+ * Duplicated atomic state or NULL when obj->state is not
+ * initialized or allocation failed.
+ */
+ void *(*duplicate_state)(struct drm_atomic_state *state, void *obj);
+
+ /**
+ * @swap_state:
+ *
+ * This function swaps the existing state of a private object @obj with
+ * it's newly created state, the pointer to which is passed as
+ * @obj_state_ptr.
+ */
+ void (*swap_state)(void *obj, void **obj_state_ptr);
+
+ /**
+ * @destroy_state:
+ *
+ * Frees the private object state created with @duplicate_state.
+ */
+ void (*destroy_state)(void *obj_state);
+};
+
+struct __drm_private_objs_state {
+ void *obj;
+ void *obj_state;
+ const struct drm_private_state_funcs *funcs;
+};
+
+/**
* struct drm_atomic_state - the global state object for atomic updates
* @ref: count of all references to this state (will not be freed until zero)
* @dev: parent DRM device
@@ -164,6 +211,8 @@ struct __drm_connnectors_state {
* @crtcs: pointer to array of CRTC pointers
* @num_connector: size of the @connectors and @connector_states arrays
* @connectors: pointer to array of structures with per-connector data
+ * @num_private_objs: size of the @private_objs array
+ * @private_objs: pointer to array of private object pointers
* @acquire_ctx: acquire context for this atomic modeset state update
*/
struct drm_atomic_state {
@@ -176,6 +225,8 @@ struct drm_atomic_state {
struct __drm_crtcs_state *crtcs;
int num_connector;
struct __drm_connnectors_state *connectors;
+ int num_private_objs;
+ struct __drm_private_objs_state *private_objs;
struct drm_modeset_acquire_ctx *acquire_ctx;
@@ -268,6 +319,11 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
struct drm_connector_state *state, struct drm_property *property,
uint64_t val);
+void * __must_check
+drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
+ void *obj,
+ const struct drm_private_state_funcs *funcs);
+
/**
* drm_atomic_get_existing_crtc_state - get crtc state, if it exists
* @state: global atomic state object
@@ -753,6 +809,45 @@ void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
for_each_if (plane)
/**
+ * __for_each_private_obj - iterate over all private objects
+ * @__state: &struct drm_atomic_state pointer
+ * @obj: private object iteration cursor
+ * @obj_state: private object state iteration cursor
+ * @__i: int iteration cursor, for macro-internal use
+ * @__funcs: &struct drm_private_state_funcs iteration cursor
+ *
+ * This macro iterates over the array containing private object data in atomic
+ * state
+ */
+#define __for_each_private_obj(__state, obj, obj_state, __i, __funcs) \
+ for ((__i) = 0; \
+ (__i) < (__state)->num_private_objs && \
+ ((obj) = (__state)->private_objs[__i].obj, \
+ (__funcs) = (__state)->private_objs[__i].funcs, \
+ (obj_state) = (__state)->private_objs[__i].obj_state, \
+ 1); \
+ (__i)++) \
+
+/**
+ * for_each_private_obj - iterate over a specify type of private object
+ * @__state: &struct drm_atomic_state pointer
+ * @obj_funcs: &struct drm_private_state_funcs function table to filter
+ * private objects
+ * @obj: private object iteration cursor
+ * @obj_state: private object state iteration cursor
+ * @__i: int iteration cursor, for macro-internal use
+ * @__funcs: &struct drm_private_state_funcs iteration cursor
+ *
+ * This macro iterates over the private objects state array while filtering the
+ * objects based on the vfunc table that is passed as @obj_funcs. New macros
+ * can be created by passing in the vfunc table associated with a specific
+ * private object.
+ */
+#define for_each_private_obj(__state, obj_funcs, obj, obj_state, __i, __funcs) \
+ __for_each_private_obj(__state, obj, obj_state, __i, __funcs) \
+ for_each_if (__funcs == obj_funcs)
+
+/**
* drm_atomic_crtc_needs_modeset - compute combined modeset need
* @state: &drm_crtc_state for the CRTC
*
diff --git a/include/drm/drm_blend.h b/include/drm/drm_blend.h
index 13221cf9b3eb..17606026590b 100644
--- a/include/drm/drm_blend.h
+++ b/include/drm/drm_blend.h
@@ -25,31 +25,15 @@
#include <linux/list.h>
#include <linux/ctype.h>
+#include <drm/drm_mode.h>
struct drm_device;
struct drm_atomic_state;
-
-/*
- * Rotation property bits. DRM_ROTATE_<degrees> rotates the image by the
- * specified amount in degrees in counter clockwise direction. DRM_REFLECT_X and
- * DRM_REFLECT_Y reflects the image along the specified axis prior to rotation
- *
- * WARNING: These defines are UABI since they're exposed in the rotation
- * property.
- */
-#define DRM_ROTATE_0 BIT(0)
-#define DRM_ROTATE_90 BIT(1)
-#define DRM_ROTATE_180 BIT(2)
-#define DRM_ROTATE_270 BIT(3)
-#define DRM_ROTATE_MASK (DRM_ROTATE_0 | DRM_ROTATE_90 | \
- DRM_ROTATE_180 | DRM_ROTATE_270)
-#define DRM_REFLECT_X BIT(4)
-#define DRM_REFLECT_Y BIT(5)
-#define DRM_REFLECT_MASK (DRM_REFLECT_X | DRM_REFLECT_Y)
+struct drm_plane;
static inline bool drm_rotation_90_or_270(unsigned int rotation)
{
- return rotation & (DRM_ROTATE_90 | DRM_ROTATE_270);
+ return rotation & (DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270);
}
int drm_plane_create_rotation_property(struct drm_plane *plane,
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index fdd82fcbf168..983054f2e86e 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -59,6 +59,40 @@ struct drm_bridge_funcs {
void (*detach)(struct drm_bridge *bridge);
/**
+ * @mode_valid:
+ *
+ * This callback is used to check if a specific mode is valid in this
+ * bridge. This should be implemented if the bridge has some sort of
+ * restriction in the modes it can display. For example, a given bridge
+ * may be responsible to set a clock value. If the clock can not
+ * produce all the values for the available modes then this callback
+ * can be used to restrict the number of modes to only the ones that
+ * can be displayed.
+ *
+ * This hook is used by the probe helpers to filter the mode list in
+ * drm_helper_probe_single_connector_modes(), and it is used by the
+ * atomic helpers to validate modes supplied by userspace in
+ * drm_atomic_helper_check_modeset().
+ *
+ * This function is optional.
+ *
+ * NOTE:
+ *
+ * Since this function is both called from the check phase of an atomic
+ * commit, and the mode validation in the probe paths it is not allowed
+ * to look at anything else but the passed-in mode, and validate it
+ * against configuration-invariant hardward constraints. Any further
+ * limits which depend upon the configuration can only be checked in
+ * @mode_fixup.
+ *
+ * RETURNS:
+ *
+ * drm_mode_status Enum
+ */
+ enum drm_mode_status (*mode_valid)(struct drm_bridge *crtc,
+ const struct drm_display_mode *mode);
+
+ /**
* @mode_fixup:
*
* This callback is used to validate and adjust a mode. The paramater
@@ -66,7 +100,7 @@ struct drm_bridge_funcs {
* the display chain, either the final &drm_connector or the next
* &drm_bridge. The parameter adjusted_mode is the input mode the bridge
* requires. It can be modified by this callback and does not need to
- * match mode.
+ * match mode. See also &drm_crtc_state.adjusted_mode for more details.
*
* This is the only hook that allows a bridge to reject a modeset. If
* this function passes all other callbacks must succeed for this
@@ -82,6 +116,12 @@ struct drm_bridge_funcs {
* NOT touch any persistent state (hardware or software) or data
* structures except the passed in @state parameter.
*
+ * Also beware that userspace can request its own custom modes, neither
+ * core nor helpers filter modes to the list of probe modes reported by
+ * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure
+ * that modes are filtered consistently put any bridge constraints and
+ * limits checks into @mode_valid.
+ *
* RETURNS:
*
* True if an acceptable configuration is possible, false if the modeset
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index bce4a532836d..03a59cbce621 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -25,6 +25,8 @@
#include <linux/ctype.h>
+struct drm_crtc;
+
uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 4eeda120e46d..2fe09c1ddfb8 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -25,6 +25,7 @@
#include <linux/list.h>
#include <linux/ctype.h>
+#include <linux/hdmi.h>
#include <drm/drm_mode_object.h>
#include <uapi/drm/drm_mode.h>
@@ -326,6 +327,21 @@ struct drm_connector_state {
struct drm_atomic_state *state;
struct drm_tv_connector_state tv;
+
+ /**
+ * @picture_aspect_ratio: Connector property to control the
+ * HDMI infoframe aspect ratio setting.
+ *
+ * The %DRM_MODE_PICTURE_ASPECT_\* values much match the
+ * values for &enum hdmi_picture_aspect
+ */
+ enum hdmi_picture_aspect picture_aspect_ratio;
+
+ /**
+ * @scaling_mode: Connector property to control the
+ * upscaling, mostly used for built-in panels.
+ */
+ unsigned int scaling_mode;
};
/**
@@ -675,6 +691,7 @@ struct drm_cmdline_mode {
* @tile_v_loc: vertical location of this tile
* @tile_h_size: horizontal size of this tile.
* @tile_v_size: vertical size of this tile.
+ * @scaling_mode_property: Optional atomic property to control the upscaling.
*
* Each connector may be connected to one or more CRTCs, or may be clonable by
* another connector if they can share a CRTC. Each connector also has a specific
@@ -754,6 +771,8 @@ struct drm_connector {
struct drm_property_blob *edid_blob_ptr;
struct drm_object_properties properties;
+ struct drm_property *scaling_mode_property;
+
/**
* @path_blob_ptr:
*
@@ -953,6 +972,8 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
unsigned int num_modes,
const char * const modes[]);
int drm_mode_create_scaling_mode_property(struct drm_device *dev);
+int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
+ u32 scaling_mode_mask);
int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
@@ -1031,7 +1052,7 @@ void drm_connector_list_iter_end(struct drm_connector_list_iter *iter);
*
* Note that @connector is only valid within the list body, if you want to use
* @connector after calling drm_connector_list_iter_end() then you need to grab
- * your own reference first using drm_connector_begin().
+ * your own reference first using drm_connector_get().
*/
#define drm_for_each_connector_iter(connector, iter) \
while ((connector = drm_connector_list_iter_next(iter)))
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index a8176a836e25..b6e3713bd7a9 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -90,14 +90,7 @@ struct drm_plane_helper_funcs;
* @plane_mask: bitmask of (1 << drm_plane_index(plane)) of attached planes
* @connector_mask: bitmask of (1 << drm_connector_index(connector)) of attached connectors
* @encoder_mask: bitmask of (1 << drm_encoder_index(encoder)) of attached encoders
- * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
- * @mode: current mode timings
* @mode_blob: &drm_property_blob for @mode
- * @degamma_lut: Lookup table for converting framebuffer pixel data
- * before apply the conversion matrix
- * @ctm: Transformation matrix
- * @gamma_lut: Lookup table for converting pixel data after the
- * conversion matrix
* @state: backpointer to global drm_atomic_state
*
* Note that the distinction between @enable and @active is rather subtile:
@@ -136,17 +129,62 @@ struct drm_crtc_state {
u32 connector_mask;
u32 encoder_mask;
- /* adjusted_mode: for use by helpers and drivers */
+ /**
+ * @adjusted_mode:
+ *
+ * Internal display timings which can be used by the driver to handle
+ * differences between the mode requested by userspace in @mode and what
+ * is actually programmed into the hardware. It is purely driver
+ * implementation defined what exactly this adjusted mode means. Usually
+ * it is used to store the hardware display timings used between the
+ * CRTC and encoder blocks.
+ */
struct drm_display_mode adjusted_mode;
+ /**
+ * @mode:
+ *
+ * Display timings requested by userspace. The driver should try to
+ * match the refresh rate as close as possible (but note that it's
+ * undefined what exactly is close enough, e.g. some of the HDMI modes
+ * only differ in less than 1% of the refresh rate). The active width
+ * and height as observed by userspace for positioning planes must match
+ * exactly.
+ *
+ * For external connectors where the sink isn't fixed (like with a
+ * built-in panel), this mode here should match the physical mode on the
+ * wire to the last details (i.e. including sync polarities and
+ * everything).
+ */
struct drm_display_mode mode;
/* blob property to expose current mode to atomic userspace */
struct drm_property_blob *mode_blob;
- /* blob property to expose color management to userspace */
+ /**
+ * @degamma_lut:
+ *
+ * Lookup table for converting framebuffer pixel data before apply the
+ * color conversion matrix @ctm. See drm_crtc_enable_color_mgmt(). The
+ * blob (if not NULL) is an array of &struct drm_color_lut.
+ */
struct drm_property_blob *degamma_lut;
+
+ /**
+ * @ctm:
+ *
+ * Color transformation matrix. See drm_crtc_enable_color_mgmt(). The
+ * blob (if not NULL) is a &struct drm_color_ctm.
+ */
struct drm_property_blob *ctm;
+
+ /**
+ * @gamma_lut:
+ *
+ * Lookup table for converting pixel data after the color conversion
+ * matrix @ctm. See drm_crtc_enable_color_mgmt(). The blob (if not
+ * NULL) is an array of &struct drm_color_lut.
+ */
struct drm_property_blob *gamma_lut;
/**
@@ -313,6 +351,12 @@ struct drm_crtc_funcs {
*
* This callback is optional.
*
+ * Atomic drivers who want to support gamma tables should implement the
+ * atomic color management support, enabled by calling
+ * drm_crtc_enable_color_mgmt(), which then supports the legacy gamma
+ * interface through the drm_atomic_helper_legacy_gamma_set()
+ * compatibility implementation.
+ *
* NOTE:
*
* Drivers that support gamma tables and also fbdev emulation through
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 23837f5dc5e1..20eb5ca28594 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -179,6 +179,111 @@
#define DP_GUID 0x030 /* 1.2 */
+#define DP_DSC_SUPPORT 0x060 /* DP 1.4 */
+# define DP_DSC_DECOMPRESSION_IS_SUPPORTED (1 << 0)
+
+#define DP_DSC_REV 0x061
+# define DP_DSC_MAJOR_MASK (0xf << 0)
+# define DP_DSC_MINOR_MASK (0xf << 4)
+# define DP_DSC_MAJOR_SHIFT 0
+# define DP_DSC_MINOR_SHIFT 4
+
+#define DP_DSC_RC_BUF_BLK_SIZE 0x062
+# define DP_DSC_RC_BUF_BLK_SIZE_1 0x0
+# define DP_DSC_RC_BUF_BLK_SIZE_4 0x1
+# define DP_DSC_RC_BUF_BLK_SIZE_16 0x2
+# define DP_DSC_RC_BUF_BLK_SIZE_64 0x3
+
+#define DP_DSC_RC_BUF_SIZE 0x063
+
+#define DP_DSC_SLICE_CAP_1 0x064
+# define DP_DSC_1_PER_DP_DSC_SINK (1 << 0)
+# define DP_DSC_2_PER_DP_DSC_SINK (1 << 1)
+# define DP_DSC_4_PER_DP_DSC_SINK (1 << 3)
+# define DP_DSC_6_PER_DP_DSC_SINK (1 << 4)
+# define DP_DSC_8_PER_DP_DSC_SINK (1 << 5)
+# define DP_DSC_10_PER_DP_DSC_SINK (1 << 6)
+# define DP_DSC_12_PER_DP_DSC_SINK (1 << 7)
+
+#define DP_DSC_LINE_BUF_BIT_DEPTH 0x065
+# define DP_DSC_LINE_BUF_BIT_DEPTH_MASK (0xf << 0)
+# define DP_DSC_LINE_BUF_BIT_DEPTH_9 0x0
+# define DP_DSC_LINE_BUF_BIT_DEPTH_10 0x1
+# define DP_DSC_LINE_BUF_BIT_DEPTH_11 0x2
+# define DP_DSC_LINE_BUF_BIT_DEPTH_12 0x3
+# define DP_DSC_LINE_BUF_BIT_DEPTH_13 0x4
+# define DP_DSC_LINE_BUF_BIT_DEPTH_14 0x5
+# define DP_DSC_LINE_BUF_BIT_DEPTH_15 0x6
+# define DP_DSC_LINE_BUF_BIT_DEPTH_16 0x7
+# define DP_DSC_LINE_BUF_BIT_DEPTH_8 0x8
+
+#define DP_DSC_BLK_PREDICTION_SUPPORT 0x066
+# define DP_DSC_BLK_PREDICTION_IS_SUPPORTED (1 << 0)
+
+#define DP_DSC_MAX_BITS_PER_PIXEL_LOW 0x067 /* eDP 1.4 */
+
+#define DP_DSC_MAX_BITS_PER_PIXEL_HI 0x068 /* eDP 1.4 */
+
+#define DP_DSC_DEC_COLOR_FORMAT_CAP 0x069
+# define DP_DSC_RGB (1 << 0)
+# define DP_DSC_YCbCr444 (1 << 1)
+# define DP_DSC_YCbCr422_Simple (1 << 2)
+# define DP_DSC_YCbCr422_Native (1 << 3)
+# define DP_DSC_YCbCr420_Native (1 << 4)
+
+#define DP_DSC_DEC_COLOR_DEPTH_CAP 0x06A
+# define DP_DSC_8_BPC (1 << 1)
+# define DP_DSC_10_BPC (1 << 2)
+# define DP_DSC_12_BPC (1 << 3)
+
+#define DP_DSC_PEAK_THROUGHPUT 0x06B
+# define DP_DSC_THROUGHPUT_MODE_0_MASK (0xf << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_SHIFT 0
+# define DP_DSC_THROUGHPUT_MODE_0_340 (1 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_400 (2 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_450 (3 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_500 (4 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_550 (5 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_600 (6 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_650 (7 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_700 (8 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_750 (9 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_800 (10 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_850 (11 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_900 (12 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_950 (13 << 0)
+# define DP_DSC_THROUGHPUT_MODE_0_1000 (14 << 0)
+# define DP_DSC_THROUGHPUT_MODE_1_MASK (0xf << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_SHIFT 4
+# define DP_DSC_THROUGHPUT_MODE_1_340 (1 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_400 (2 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_450 (3 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_500 (4 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_550 (5 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_600 (6 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_650 (7 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_700 (8 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_750 (9 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_800 (10 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_850 (11 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_900 (12 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_950 (13 << 4)
+# define DP_DSC_THROUGHPUT_MODE_1_1000 (14 << 4)
+
+#define DP_DSC_MAX_SLICE_WIDTH 0x06C
+
+#define DP_DSC_SLICE_CAP_2 0x06D
+# define DP_DSC_16_PER_DP_DSC_SINK (1 << 0)
+# define DP_DSC_20_PER_DP_DSC_SINK (1 << 1)
+# define DP_DSC_24_PER_DP_DSC_SINK (1 << 2)
+
+#define DP_DSC_BITS_PER_PIXEL_INC 0x06F
+# define DP_DSC_BITS_PER_PIXEL_1_16 0x0
+# define DP_DSC_BITS_PER_PIXEL_1_8 0x1
+# define DP_DSC_BITS_PER_PIXEL_1_4 0x2
+# define DP_DSC_BITS_PER_PIXEL_1_2 0x3
+# define DP_DSC_BITS_PER_PIXEL_1 0x4
+
#define DP_PSR_SUPPORT 0x070 /* XXX 1.2? */
# define DP_PSR_IS_SUPPORTED 1
# define DP_PSR2_IS_SUPPORTED 2 /* eDP 1.4 */
@@ -339,6 +444,8 @@
#define DP_AUX_FRAME_SYNC_VALUE 0x15c /* eDP 1.4 */
# define DP_AUX_FRAME_SYNC_VALID (1 << 0)
+#define DP_DSC_ENABLE 0x160 /* DP 1.4 */
+
#define DP_PSR_EN_CFG 0x170 /* XXX 1.2? */
# define DP_PSR_ENABLE (1 << 0)
# define DP_PSR_MAIN_LINK_ACTIVE (1 << 1)
@@ -605,6 +712,9 @@
#define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0 0x2003 /* 1.2 */
#define DP_DEVICE_SERVICE_IRQ_VECTOR_ESI1 0x2004 /* 1.2 */
+# define DP_RX_GTC_MSTR_REQ_STATUS_CHANGE (1 << 0)
+# define DP_LOCK_ACQUISITION_REQUEST (1 << 1)
+# define DP_CEC_IRQ (1 << 2)
#define DP_LINK_SERVICE_IRQ_VECTOR_ESI0 0x2005 /* 1.2 */
@@ -638,6 +748,62 @@
# define DP_VSC_EXT_CEA_SDP_SUPPORTED (1 << 6) /* DP 1.4 */
# define DP_VSC_EXT_CEA_SDP_CHAINING_SUPPORTED (1 << 7) /* DP 1.4 */
+/* HDMI CEC tunneling over AUX DP 1.3 section 5.3.3.3.1 DPCD 1.4+ */
+#define DP_CEC_TUNNELING_CAPABILITY 0x3000
+# define DP_CEC_TUNNELING_CAPABLE (1 << 0)
+# define DP_CEC_SNOOPING_CAPABLE (1 << 1)
+# define DP_CEC_MULTIPLE_LA_CAPABLE (1 << 2)
+
+#define DP_CEC_TUNNELING_CONTROL 0x3001
+# define DP_CEC_TUNNELING_ENABLE (1 << 0)
+# define DP_CEC_SNOOPING_ENABLE (1 << 1)
+
+#define DP_CEC_RX_MESSAGE_INFO 0x3002
+# define DP_CEC_RX_MESSAGE_LEN_MASK (0xf << 0)
+# define DP_CEC_RX_MESSAGE_LEN_SHIFT 0
+# define DP_CEC_RX_MESSAGE_HPD_STATE (1 << 4)
+# define DP_CEC_RX_MESSAGE_HPD_LOST (1 << 5)
+# define DP_CEC_RX_MESSAGE_ACKED (1 << 6)
+# define DP_CEC_RX_MESSAGE_ENDED (1 << 7)
+
+#define DP_CEC_TX_MESSAGE_INFO 0x3003
+# define DP_CEC_TX_MESSAGE_LEN_MASK (0xf << 0)
+# define DP_CEC_TX_MESSAGE_LEN_SHIFT 0
+# define DP_CEC_TX_RETRY_COUNT_MASK (0x7 << 4)
+# define DP_CEC_TX_RETRY_COUNT_SHIFT 4
+# define DP_CEC_TX_MESSAGE_SEND (1 << 7)
+
+#define DP_CEC_TUNNELING_IRQ_FLAGS 0x3004
+# define DP_CEC_RX_MESSAGE_INFO_VALID (1 << 0)
+# define DP_CEC_RX_MESSAGE_OVERFLOW (1 << 1)
+# define DP_CEC_TX_MESSAGE_SENT (1 << 4)
+# define DP_CEC_TX_LINE_ERROR (1 << 5)
+# define DP_CEC_TX_ADDRESS_NACK_ERROR (1 << 6)
+# define DP_CEC_TX_DATA_NACK_ERROR (1 << 7)
+
+#define DP_CEC_LOGICAL_ADDRESS_MASK 0x300E /* 0x300F word */
+# define DP_CEC_LOGICAL_ADDRESS_0 (1 << 0)
+# define DP_CEC_LOGICAL_ADDRESS_1 (1 << 1)
+# define DP_CEC_LOGICAL_ADDRESS_2 (1 << 2)
+# define DP_CEC_LOGICAL_ADDRESS_3 (1 << 3)
+# define DP_CEC_LOGICAL_ADDRESS_4 (1 << 4)
+# define DP_CEC_LOGICAL_ADDRESS_5 (1 << 5)
+# define DP_CEC_LOGICAL_ADDRESS_6 (1 << 6)
+# define DP_CEC_LOGICAL_ADDRESS_7 (1 << 7)
+#define DP_CEC_LOGICAL_ADDRESS_MASK_2 0x300F /* 0x300E word */
+# define DP_CEC_LOGICAL_ADDRESS_8 (1 << 0)
+# define DP_CEC_LOGICAL_ADDRESS_9 (1 << 1)
+# define DP_CEC_LOGICAL_ADDRESS_10 (1 << 2)
+# define DP_CEC_LOGICAL_ADDRESS_11 (1 << 3)
+# define DP_CEC_LOGICAL_ADDRESS_12 (1 << 4)
+# define DP_CEC_LOGICAL_ADDRESS_13 (1 << 5)
+# define DP_CEC_LOGICAL_ADDRESS_14 (1 << 6)
+# define DP_CEC_LOGICAL_ADDRESS_15 (1 << 7)
+
+#define DP_CEC_RX_MESSAGE_BUFFER 0x3010
+#define DP_CEC_TX_MESSAGE_BUFFER 0x3020
+#define DP_CEC_MESSAGE_BUFFER_LENGTH 0x10
+
/* DP 1.2 Sideband message defines */
/* peer device type - DP 1.2a Table 2-92 */
#define DP_PEER_DEVICE_NONE 0x0
diff --git a/include/drm/drm_dp_mst_helper.h b/include/drm/drm_dp_mst_helper.h
index 5b024764666c..177ab6f86855 100644
--- a/include/drm/drm_dp_mst_helper.h
+++ b/include/drm/drm_dp_mst_helper.h
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <drm/drm_dp_helper.h>
+#include <drm/drm_atomic.h>
struct drm_dp_mst_branch;
@@ -403,6 +404,12 @@ struct drm_dp_payload {
int vcpi;
};
+struct drm_dp_mst_topology_state {
+ int avail_slots;
+ struct drm_atomic_state *state;
+ struct drm_dp_mst_topology_mgr *mgr;
+};
+
/**
* struct drm_dp_mst_topology_mgr - DisplayPort MST manager
*
@@ -481,6 +488,16 @@ struct drm_dp_mst_topology_mgr {
int pbn_div;
/**
+ * @state: State information for topology manager
+ */
+ struct drm_dp_mst_topology_state *state;
+
+ /**
+ * @funcs: Atomic helper callbacks
+ */
+ const struct drm_private_state_funcs *funcs;
+
+ /**
* @qlock: protects @tx_msg_downq, the &drm_dp_mst_branch.txslost and
* &drm_dp_sideband_msg_tx.state once they are queued
*/
@@ -596,4 +613,13 @@ void drm_dp_mst_dump_topology(struct seq_file *m,
void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr);
int drm_dp_mst_topology_mgr_resume(struct drm_dp_mst_topology_mgr *mgr);
+struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct drm_atomic_state *state,
+ struct drm_dp_mst_topology_mgr *mgr);
+int drm_dp_atomic_find_vcpi_slots(struct drm_atomic_state *state,
+ struct drm_dp_mst_topology_mgr *mgr,
+ struct drm_dp_mst_port *port, int pbn);
+int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
+ struct drm_dp_mst_topology_mgr *mgr,
+ int slots);
+
#endif
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 53b98321df9b..e64e33b9dd26 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -104,23 +104,6 @@ struct drm_driver {
int (*open) (struct drm_device *, struct drm_file *);
/**
- * @preclose:
- *
- * One of the driver callbacks when a new &struct drm_file is closed.
- * Useful for tearing down driver-private data structures allocated in
- * @open like buffer allocators, execution contexts or similar things.
- *
- * Since the display/modeset side of DRM can only be owned by exactly
- * one &struct drm_file (see &drm_file.is_master and &drm_device.master)
- * there should never be a need to tear down any modeset related
- * resources in this callback. Doing so would be a driver design bug.
- *
- * FIXME: It is not really clear why there's both @preclose and
- * @postclose. Without a really good reason, use @postclose only.
- */
- void (*preclose) (struct drm_device *, struct drm_file *file_priv);
-
- /**
* @postclose:
*
* One of the driver callbacks when a new &struct drm_file is closed.
@@ -131,9 +114,6 @@ struct drm_driver {
* one &struct drm_file (see &drm_file.is_master and &drm_device.master)
* there should never be a need to tear down any modeset related
* resources in this callback. Doing so would be a driver design bug.
- *
- * FIXME: It is not really clear why there's both @preclose and
- * @postclose. Without a really good reason, use @postclose only.
*/
void (*postclose) (struct drm_device *, struct drm_file *);
@@ -150,7 +130,7 @@ struct drm_driver {
* state changes, e.g. in conjunction with the :ref:`vga_switcheroo`
* infrastructure.
*
- * This is called after @preclose and @postclose have been called.
+ * This is called after @postclose hook has been called.
*
* NOTE:
*
@@ -261,8 +241,10 @@ struct drm_driver {
* DRM device.
* pipe:
* Id of the crtc to query.
- * flags:
- * Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0).
+ * in_vblank_irq:
+ * True when called from drm_crtc_handle_vblank(). Some drivers
+ * need to apply some workarounds for gpu-specific vblank irq quirks
+ * if flag is set.
* vpos:
* Target location for current vertical scanout position.
* hpos:
@@ -283,22 +265,19 @@ struct drm_driver {
*
* Returns:
*
- * Flags, or'ed together as follows:
+ * True on success, false if a reliable scanout position counter could
+ * not be read out.
*
- * DRM_SCANOUTPOS_VALID:
- * Query successful.
- * DRM_SCANOUTPOS_INVBL:
- * Inside vblank.
- * DRM_SCANOUTPOS_ACCURATE: Returned position is accurate. A lack of
- * this flag means that returned position may be offset by a
- * constant but unknown small number of scanlines wrt. real scanout
- * position.
+ * FIXME:
*
+ * Since this is a helper to implement @get_vblank_timestamp, we should
+ * move it to &struct drm_crtc_helper_funcs, like all the other
+ * helper-internal hooks.
*/
- int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe,
- unsigned int flags, int *vpos, int *hpos,
- ktime_t *stime, ktime_t *etime,
- const struct drm_display_mode *mode);
+ bool (*get_scanout_position) (struct drm_device *dev, unsigned int pipe,
+ bool in_vblank_irq, int *vpos, int *hpos,
+ ktime_t *stime, ktime_t *etime,
+ const struct drm_display_mode *mode);
/**
* @get_vblank_timestamp:
@@ -328,22 +307,25 @@ struct drm_driver {
* Returns true upper bound on error for timestamp.
* vblank_time:
* Target location for returned vblank timestamp.
- * flags:
- * 0 = Defaults, no special treatment needed.
- * DRM_CALLED_FROM_VBLIRQ = Function is called from vblank
- * irq handler. Some drivers need to apply some workarounds
- * for gpu-specific vblank irq quirks if flag is set.
+ * in_vblank_irq:
+ * True when called from drm_crtc_handle_vblank(). Some drivers
+ * need to apply some workarounds for gpu-specific vblank irq quirks
+ * if flag is set.
*
* Returns:
*
- * Zero if timestamping isn't supported in current display mode or a
- * negative number on failure. A positive status code on success,
- * which describes how the vblank_time timestamp was computed.
+ * True on success, false on failure, which means the core should
+ * fallback to a simple timestamp taken in drm_crtc_handle_vblank().
+ *
+ * FIXME:
+ *
+ * We should move this hook to &struct drm_crtc_funcs like all the other
+ * vblank hooks.
*/
- int (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe,
+ bool (*get_vblank_timestamp) (struct drm_device *dev, unsigned int pipe,
int *max_error,
struct timeval *vblank_time,
- unsigned flags);
+ bool in_vblank_irq);
/* these have to be filled in */
@@ -516,6 +498,7 @@ struct drm_driver {
/* List of devices hanging off this driver with stealth attach. */
struct list_head legacy_dev_list;
int (*firstopen) (struct drm_device *);
+ void (*preclose) (struct drm_device *, struct drm_file *file_priv);
int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
int (*dma_quiescent) (struct drm_device *);
int (*context_dtor) (struct drm_device *dev, int context);
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h
index a5ecc0a58260..199a63f48659 100644
--- a/include/drm/drm_fb_cma_helper.h
+++ b/include/drm/drm_fb_cma_helper.h
@@ -41,6 +41,10 @@ struct drm_framebuffer *drm_fb_cma_create(struct drm_device *dev,
struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
unsigned int plane);
+dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
+ struct drm_plane_state *state,
+ unsigned int plane);
+
int drm_fb_cma_prepare_fb(struct drm_plane *plane,
struct drm_plane_state *state);
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index f962d33667cf..b42529e0fae0 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -26,6 +26,13 @@ to_drm_gem_cma_obj(struct drm_gem_object *gem_obj)
return container_of(gem_obj, struct drm_gem_cma_object, base);
}
+#ifndef CONFIG_MMU
+#define DRM_GEM_CMA_UNMAPPED_AREA_FOPS \
+ .get_unmapped_area = drm_gem_cma_get_unmapped_area,
+#else
+#define DRM_GEM_CMA_UNMAPPED_AREA_FOPS
+#endif
+
/**
* DEFINE_DRM_GEM_CMA_FOPS() - macro to generate file operations for CMA drivers
* @name: name for the generated structure
@@ -50,6 +57,7 @@ to_drm_gem_cma_obj(struct drm_gem_object *gem_obj)
.read = drm_read,\
.llseek = noop_llseek,\
.mmap = drm_gem_cma_mmap,\
+ DRM_GEM_CMA_UNMAPPED_AREA_FOPS \
}
/* free GEM object */
@@ -85,15 +93,6 @@ unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
unsigned long len,
unsigned long pgoff,
unsigned long flags);
-#else
-static inline unsigned long drm_gem_cma_get_unmapped_area(struct file *filp,
- unsigned long addr,
- unsigned long len,
- unsigned long pgoff,
- unsigned long flags)
-{
- return -EINVAL;
-}
#endif
#ifdef CONFIG_DEBUG_FS
diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h
index cf0be6594c8c..569ca86d4e1f 100644
--- a/include/drm/drm_irq.h
+++ b/include/drm/drm_irq.h
@@ -121,6 +121,18 @@ struct drm_vblank_crtc {
* drm_calc_timestamping_constants().
*/
int linedur_ns;
+
+ /**
+ * @hwmode:
+ *
+ * Cache of the current hardware display mode. Only valid when @enabled
+ * is set. This is used by helpers like
+ * drm_calc_vbltimestamp_from_scanoutpos(). We can't just access the
+ * hardware mode by e.g. looking at &drm_crtc_state.adjusted_mode,
+ * because that one is really hard to get from interrupt context.
+ */
+ struct drm_display_mode hwmode;
+
/**
* @enabled: Tracks the enabling state of the corresponding &drm_crtc to
* avoid double-disabling and hence corrupting saved state. Needed by
@@ -153,11 +165,10 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc);
void drm_vblank_cleanup(struct drm_device *dev);
u32 drm_accurate_vblank_count(struct drm_crtc *crtc);
-int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
- unsigned int pipe, int *max_error,
- struct timeval *vblank_time,
- unsigned flags,
- const struct drm_display_mode *mode);
+bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
+ unsigned int pipe, int *max_error,
+ struct timeval *vblank_time,
+ bool in_vblank_irq);
void drm_calc_timestamping_constants(struct drm_crtc *crtc,
const struct drm_display_mode *mode);
diff --git a/include/drm/drm_mem_util.h b/include/drm/drm_mem_util.h
deleted file mode 100644
index 70d4e221a3ad..000000000000
--- a/include/drm/drm_mem_util.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright © 2008 Intel Corporation
- *
- * 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 (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 NONINFRINGEMENT. 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.
- *
- * Authors:
- * Jesse Barnes <jbarnes@virtuousgeek.org>
- *
- */
-#ifndef _DRM_MEM_UTIL_H_
-#define _DRM_MEM_UTIL_H_
-
-#include <linux/vmalloc.h>
-
-static __inline__ void *drm_calloc_large(size_t nmemb, size_t size)
-{
- if (size != 0 && nmemb > SIZE_MAX / size)
- return NULL;
-
- if (size * nmemb <= PAGE_SIZE)
- return kcalloc(nmemb, size, GFP_KERNEL);
-
- return __vmalloc(size * nmemb,
- GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
-}
-
-/* Modeled after cairo's malloc_ab, it's like calloc but without the zeroing. */
-static __inline__ void *drm_malloc_ab(size_t nmemb, size_t size)
-{
- if (size != 0 && nmemb > SIZE_MAX / size)
- return NULL;
-
- if (size * nmemb <= PAGE_SIZE)
- return kmalloc(nmemb * size, GFP_KERNEL);
-
- return __vmalloc(size * nmemb,
- GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
-static __inline__ void *drm_malloc_gfp(size_t nmemb, size_t size, gfp_t gfp)
-{
- if (size != 0 && nmemb > SIZE_MAX / size)
- return NULL;
-
- if (size * nmemb <= PAGE_SIZE)
- return kmalloc(nmemb * size, gfp);
-
- if (gfp & __GFP_RECLAIMABLE) {
- void *ptr = kmalloc(nmemb * size,
- gfp | __GFP_NOWARN | __GFP_NORETRY);
- if (ptr)
- return ptr;
- }
-
- return __vmalloc(size * nmemb,
- gfp | __GFP_HIGHMEM, PAGE_KERNEL);
-}
-
-static __inline void drm_free_large(void *ptr)
-{
- kvfree(ptr);
-}
-
-#endif
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index c01c328f6cc8..85984b208218 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -106,6 +106,40 @@ struct drm_crtc_helper_funcs {
void (*commit)(struct drm_crtc *crtc);
/**
+ * @mode_valid:
+ *
+ * This callback is used to check if a specific mode is valid in this
+ * crtc. This should be implemented if the crtc has some sort of
+ * restriction in the modes it can display. For example, a given crtc
+ * may be responsible to set a clock value. If the clock can not
+ * produce all the values for the available modes then this callback
+ * can be used to restrict the number of modes to only the ones that
+ * can be displayed.
+ *
+ * This hook is used by the probe helpers to filter the mode list in
+ * drm_helper_probe_single_connector_modes(), and it is used by the
+ * atomic helpers to validate modes supplied by userspace in
+ * drm_atomic_helper_check_modeset().
+ *
+ * This function is optional.
+ *
+ * NOTE:
+ *
+ * Since this function is both called from the check phase of an atomic
+ * commit, and the mode validation in the probe paths it is not allowed
+ * to look at anything else but the passed-in mode, and validate it
+ * against configuration-invariant hardward constraints. Any further
+ * limits which depend upon the configuration can only be checked in
+ * @mode_fixup or @atomic_check.
+ *
+ * RETURNS:
+ *
+ * drm_mode_status Enum
+ */
+ enum drm_mode_status (*mode_valid)(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode);
+
+ /**
* @mode_fixup:
*
* This callback is used to validate a mode. The parameter mode is the
@@ -113,7 +147,8 @@ struct drm_crtc_helper_funcs {
* encoders need to be fed with. Note that this is the inverse semantics
* of the meaning for the &drm_encoder and &drm_bridge_funcs.mode_fixup
* vfunc. If the CRTC cannot support the requested conversion from mode
- * to adjusted_mode it should reject the modeset.
+ * to adjusted_mode it should reject the modeset. See also
+ * &drm_crtc_state.adjusted_mode for more details.
*
* This function is used by both legacy CRTC helpers and atomic helpers.
* With atomic helpers it is optional.
@@ -130,22 +165,17 @@ struct drm_crtc_helper_funcs {
* allowed.
*
* Atomic drivers which need to inspect and adjust more state should
- * instead use the @atomic_check callback.
- *
- * Also beware that neither core nor helpers filter modes before
- * passing them to the driver: While the list of modes that is
- * advertised to userspace is filtered using the
- * &drm_connector.mode_valid callback, neither the core nor the helpers
- * do any filtering on modes passed in from userspace when setting a
- * mode. It is therefore possible for userspace to pass in a mode that
- * was previously filtered out using &drm_connector.mode_valid or add a
- * custom mode that wasn't probed from EDID or similar to begin with.
- * Even though this is an advanced feature and rarely used nowadays,
- * some users rely on being able to specify modes manually so drivers
- * must be prepared to deal with it. Specifically this means that all
- * drivers need not only validate modes in &drm_connector.mode_valid but
- * also in this or in the &drm_encoder_helper_funcs.mode_fixup callback
- * to make sure invalid modes passed in from userspace are rejected.
+ * instead use the @atomic_check callback, but note that they're not
+ * perfectly equivalent: @mode_valid is called from
+ * drm_atomic_helper_check_modeset(), but @atomic_check is called from
+ * drm_atomic_helper_check_planes(), because originally it was meant for
+ * plane update checks only.
+ *
+ * Also beware that userspace can request its own custom modes, neither
+ * core nor helpers filter modes to the list of probe modes reported by
+ * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure
+ * that modes are filtered consistently put any CRTC constraints and
+ * limits checks into @mode_valid.
*
* RETURNS:
*
@@ -341,6 +371,12 @@ struct drm_crtc_helper_funcs {
* state objects passed-in or assembled in the overall &drm_atomic_state
* update tracking structure.
*
+ * Also beware that userspace can request its own custom modes, neither
+ * core nor helpers filter modes to the list of probe modes reported by
+ * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure
+ * that modes are filtered consistently put any CRTC constraints and
+ * limits checks into @mode_valid.
+ *
* RETURNS:
*
* 0 on success, -EINVAL if the state or the transition can't be
@@ -457,13 +493,48 @@ struct drm_encoder_helper_funcs {
void (*dpms)(struct drm_encoder *encoder, int mode);
/**
+ * @mode_valid:
+ *
+ * This callback is used to check if a specific mode is valid in this
+ * encoder. This should be implemented if the encoder has some sort
+ * of restriction in the modes it can display. For example, a given
+ * encoder may be responsible to set a clock value. If the clock can
+ * not produce all the values for the available modes then this callback
+ * can be used to restrict the number of modes to only the ones that
+ * can be displayed.
+ *
+ * This hook is used by the probe helpers to filter the mode list in
+ * drm_helper_probe_single_connector_modes(), and it is used by the
+ * atomic helpers to validate modes supplied by userspace in
+ * drm_atomic_helper_check_modeset().
+ *
+ * This function is optional.
+ *
+ * NOTE:
+ *
+ * Since this function is both called from the check phase of an atomic
+ * commit, and the mode validation in the probe paths it is not allowed
+ * to look at anything else but the passed-in mode, and validate it
+ * against configuration-invariant hardward constraints. Any further
+ * limits which depend upon the configuration can only be checked in
+ * @mode_fixup or @atomic_check.
+ *
+ * RETURNS:
+ *
+ * drm_mode_status Enum
+ */
+ enum drm_mode_status (*mode_valid)(struct drm_encoder *crtc,
+ const struct drm_display_mode *mode);
+
+ /**
* @mode_fixup:
*
* This callback is used to validate and adjust a mode. The parameter
* mode is the display mode that should be fed to the next element in
* the display chain, either the final &drm_connector or a &drm_bridge.
* The parameter adjusted_mode is the input mode the encoder requires. It
- * can be modified by this callback and does not need to match mode.
+ * can be modified by this callback and does not need to match mode. See
+ * also &drm_crtc_state.adjusted_mode for more details.
*
* This function is used by both legacy CRTC helpers and atomic helpers.
* This hook is optional.
@@ -480,23 +551,15 @@ struct drm_encoder_helper_funcs {
* allowed.
*
* Atomic drivers which need to inspect and adjust more state should
- * instead use the @atomic_check callback.
- *
- * Also beware that neither core nor helpers filter modes before
- * passing them to the driver: While the list of modes that is
- * advertised to userspace is filtered using the connector's
- * &drm_connector_helper_funcs.mode_valid callback, neither the core nor
- * the helpers do any filtering on modes passed in from userspace when
- * setting a mode. It is therefore possible for userspace to pass in a
- * mode that was previously filtered out using
- * &drm_connector_helper_funcs.mode_valid or add a custom mode that
- * wasn't probed from EDID or similar to begin with. Even though this
- * is an advanced feature and rarely used nowadays, some users rely on
- * being able to specify modes manually so drivers must be prepared to
- * deal with it. Specifically this means that all drivers need not only
- * validate modes in &drm_connector.mode_valid but also in this or in
- * the &drm_crtc_helper_funcs.mode_fixup callback to make sure
- * invalid modes passed in from userspace are rejected.
+ * instead use the @atomic_check callback. If @atomic_check is used,
+ * this hook isn't called since @atomic_check allows a strict superset
+ * of the functionality of @mode_fixup.
+ *
+ * Also beware that userspace can request its own custom modes, neither
+ * core nor helpers filter modes to the list of probe modes reported by
+ * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure
+ * that modes are filtered consistently put any encoder constraints and
+ * limits checks into @mode_valid.
*
* RETURNS:
*
@@ -677,6 +740,11 @@ struct drm_encoder_helper_funcs {
* update the CRTC to match what the encoder needs for the requested
* connector.
*
+ * Since this provides a strict superset of the functionality of
+ * @mode_fixup (the requested and adjusted modes are both available
+ * through the passed in &struct drm_crtc_state) @mode_fixup is not
+ * called when @atomic_check is implemented.
+ *
* This function is used by the atomic helpers, but it is optional.
*
* NOTE:
@@ -686,6 +754,12 @@ struct drm_encoder_helper_funcs {
* state objects passed-in or assembled in the overall &drm_atomic_state
* update tracking structure.
*
+ * Also beware that userspace can request its own custom modes, neither
+ * core nor helpers filter modes to the list of probe modes reported by
+ * the GETCONNECTOR IOCTL and stored in &drm_connector.modes. To ensure
+ * that modes are filtered consistently put any encoder constraints and
+ * limits checks into @mode_valid.
+ *
* RETURNS:
*
* 0 on success, -EINVAL if the state or the transition can't be
@@ -795,13 +869,20 @@ struct drm_connector_helper_funcs {
* (which is usually derived from the EDID data block from the sink).
* See e.g. drm_helper_probe_single_connector_modes().
*
+ * This function is optional.
+ *
* NOTE:
*
* This only filters the mode list supplied to userspace in the
- * GETCONNECOTR IOCTL. Userspace is free to create modes of its own and
- * ask the kernel to use them. It this case the atomic helpers or legacy
- * CRTC helpers will not call this function. Drivers therefore must
- * still fully validate any mode passed in in a modeset request.
+ * GETCONNECTOR IOCTL. Compared to &drm_encoder_helper_funcs.mode_valid,
+ * &drm_crtc_helper_funcs.mode_valid and &drm_bridge_funcs.mode_valid,
+ * which are also called by the atomic helpers from
+ * drm_atomic_helper_check_modeset(). This allows userspace to force and
+ * ignore sink constraint (like the pixel clock limits in the screen's
+ * EDID), which is useful for e.g. testing, or working around a broken
+ * EDID. Any source hardware constraint (which always need to be
+ * enforced) therefore should be checked in one of the above callbacks,
+ * and not this one here.
*
* To avoid races with concurrent connector state updates, the helper
* libraries always call this with the &drm_mode_config.connection_mutex
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 1b364b0100f4..14ac240a1f64 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -24,8 +24,10 @@
#ifndef __DRM_PANEL_H__
#define __DRM_PANEL_H__
+#include <linux/errno.h>
#include <linux/list.h>
+struct device_node;
struct drm_connector;
struct drm_device;
struct drm_panel;
diff --git a/include/drm/drm_prime.h b/include/drm/drm_prime.h
index 0b2a235c4be0..59ccab402e85 100644
--- a/include/drm/drm_prime.h
+++ b/include/drm/drm_prime.h
@@ -50,6 +50,8 @@ struct drm_prime_file_private {
struct rb_root handles;
};
+struct device;
+
struct dma_buf_export_info;
struct dma_buf;
@@ -65,6 +67,11 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
int *prime_fd);
struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf);
+
+struct drm_gem_object *drm_gem_prime_import_dev(struct drm_device *dev,
+ struct dma_buf *dma_buf,
+ struct device *attach_dev);
+
int drm_gem_prime_fd_to_handle(struct drm_device *dev,
struct drm_file *file_priv, int prime_fd, uint32_t *handle);
struct dma_buf *drm_gem_dmabuf_export(struct drm_device *dev,
diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
index 6bbd34d25a8d..990d529f823c 100644
--- a/include/drm/ttm/ttm_bo_driver.h
+++ b/include/drm/ttm/ttm_bo_driver.h
@@ -30,10 +30,6 @@
#ifndef _TTM_BO_DRIVER_H_
#define _TTM_BO_DRIVER_H_
-#include <ttm/ttm_bo_api.h>
-#include <ttm/ttm_memory.h>
-#include <ttm/ttm_module.h>
-#include <ttm/ttm_placement.h>
#include <drm/drm_mm.h>
#include <drm/drm_global.h>
#include <drm/drm_vma_manager.h>
@@ -42,6 +38,11 @@
#include <linux/spinlock.h>
#include <linux/reservation.h>
+#include "ttm_bo_api.h"
+#include "ttm_memory.h"
+#include "ttm_module.h"
+#include "ttm_placement.h"
+
#define TTM_MAX_BO_PRIORITY 4U
struct ttm_backend_func {
diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h
index 47f35b8e6d09..b0fdd1980034 100644
--- a/include/drm/ttm/ttm_execbuf_util.h
+++ b/include/drm/ttm/ttm_execbuf_util.h
@@ -31,9 +31,10 @@
#ifndef _TTM_EXECBUF_UTIL_H_
#define _TTM_EXECBUF_UTIL_H_
-#include <ttm/ttm_bo_api.h>
#include <linux/list.h>
+#include "ttm_bo_api.h"
+
/**
* struct ttm_validate_buffer
*
diff --git a/include/drm/ttm/ttm_lock.h b/include/drm/ttm/ttm_lock.h
index 2902beb5f689..0c3af9836863 100644
--- a/include/drm/ttm/ttm_lock.h
+++ b/include/drm/ttm/ttm_lock.h
@@ -49,10 +49,11 @@
#ifndef _TTM_LOCK_H_
#define _TTM_LOCK_H_
-#include <ttm/ttm_object.h>
#include <linux/wait.h>
#include <linux/atomic.h>
+#include "ttm_object.h"
+
/**
* struct ttm_lock
*
diff --git a/include/drm/ttm/ttm_object.h b/include/drm/ttm/ttm_object.h
index 1487011fe057..a98bfeb4239e 100644
--- a/include/drm/ttm/ttm_object.h
+++ b/include/drm/ttm/ttm_object.h
@@ -42,7 +42,8 @@
#include <linux/kref.h>
#include <linux/rcupdate.h>
#include <linux/dma-buf.h>
-#include <ttm/ttm_memory.h>
+
+#include "ttm_memory.h"
/**
* enum ttm_ref_type