summary refs log tree commit diff
path: root/include/drm
diff options
context:
space:
mode:
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/drmP.h19
-rw-r--r--include/drm/drm_atomic_helper.h1
-rw-r--r--include/drm/drm_client.h139
-rw-r--r--include/drm/drm_connector.h241
-rw-r--r--include/drm/drm_crtc.h263
-rw-r--r--include/drm/drm_debugfs_crc.h3
-rw-r--r--include/drm/drm_device.h21
-rw-r--r--include/drm/drm_dp_helper.h56
-rw-r--r--include/drm/drm_drv.h29
-rw-r--r--include/drm/drm_fb_cma_helper.h6
-rw-r--r--include/drm/drm_fb_helper.h38
-rw-r--r--include/drm/drm_fourcc.h2
-rw-r--r--include/drm/drm_modes.h2
-rw-r--r--include/drm/drm_modeset_helper_vtables.h8
-rw-r--r--include/drm/drm_panel.h2
-rw-r--r--include/drm/drm_plane.h174
-rw-r--r--include/drm/drm_print.h6
-rw-r--r--include/drm/drm_property.h4
-rw-r--r--include/drm/drm_vma_manager.h1
-rw-r--r--include/drm/drm_writeback.h6
-rw-r--r--include/drm/i915_drm.h4
-rw-r--r--include/drm/tinydrm/tinydrm.h23
22 files changed, 819 insertions, 229 deletions
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index c5dfbdb7271d..f7a19c2a7a80 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -102,25 +102,6 @@ struct pci_controller;
 #define DRM_SWITCH_POWER_CHANGING 2
 #define DRM_SWITCH_POWER_DYNAMIC_OFF 3
 
-static inline bool drm_core_check_feature(struct drm_device *dev, int feature)
-{
-	return dev->driver->driver_features & feature;
-}
-
-/**
- * drm_drv_uses_atomic_modeset - check if the driver implements
- * atomic_commit()
- * @dev: DRM device
- *
- * This check is useful if drivers do not have DRIVER_ATOMIC set but
- * have atomic modesetting internally implemented.
- */
-static inline bool drm_drv_uses_atomic_modeset(struct drm_device *dev)
-{
-	return drm_core_check_feature(dev, DRIVER_ATOMIC) ||
-		dev->mode_config.funcs->atomic_commit != NULL;
-}
-
 /* returns true if currently okay to sleep */
 static inline bool drm_can_sleep(void)
 {
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 26aaba58d6ce..99e2a5297c69 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -100,6 +100,7 @@ int __must_check drm_atomic_helper_swap_state(struct drm_atomic_state *state,
 int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
 				   bool nonblock);
 void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *state);
+void drm_atomic_helper_fake_vblank(struct drm_atomic_state *state);
 void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *state);
 void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *state);
 
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
new file mode 100644
index 000000000000..989f8e52864d
--- /dev/null
+++ b/include/drm/drm_client.h
@@ -0,0 +1,139 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _DRM_CLIENT_H_
+#define _DRM_CLIENT_H_
+
+#include <linux/types.h>
+
+struct drm_client_dev;
+struct drm_device;
+struct drm_file;
+struct drm_framebuffer;
+struct drm_gem_object;
+struct drm_minor;
+struct module;
+
+/**
+ * struct drm_client_funcs - DRM client callbacks
+ */
+struct drm_client_funcs {
+	/**
+	 * @owner: The module owner
+	 */
+	struct module *owner;
+
+	/**
+	 * @unregister:
+	 *
+	 * Called when &drm_device is unregistered. The client should respond by
+	 * releasing it's resources using drm_client_release().
+	 *
+	 * This callback is optional.
+	 */
+	void (*unregister)(struct drm_client_dev *client);
+
+	/**
+	 * @restore:
+	 *
+	 * Called on drm_lastclose(). The first client instance in the list that
+	 * returns zero gets the privilege to restore and no more clients are
+	 * called. This callback is not called after @unregister has been called.
+	 *
+	 * This callback is optional.
+	 */
+	int (*restore)(struct drm_client_dev *client);
+
+	/**
+	 * @hotplug:
+	 *
+	 * Called on drm_kms_helper_hotplug_event().
+	 * This callback is not called after @unregister has been called.
+	 *
+	 * This callback is optional.
+	 */
+	int (*hotplug)(struct drm_client_dev *client);
+};
+
+/**
+ * struct drm_client_dev - DRM client instance
+ */
+struct drm_client_dev {
+	/**
+	 * @dev: DRM device
+	 */
+	struct drm_device *dev;
+
+	/**
+	 * @name: Name of the client.
+	 */
+	const char *name;
+
+	/**
+	 * @list:
+	 *
+	 * List of all clients of a DRM device, linked into
+	 * &drm_device.clientlist. Protected by &drm_device.clientlist_mutex.
+	 */
+	struct list_head list;
+
+	/**
+	 * @funcs: DRM client functions (optional)
+	 */
+	const struct drm_client_funcs *funcs;
+
+	/**
+	 * @file: DRM file
+	 */
+	struct drm_file *file;
+};
+
+int drm_client_new(struct drm_device *dev, struct drm_client_dev *client,
+		   const char *name, const struct drm_client_funcs *funcs);
+void drm_client_release(struct drm_client_dev *client);
+
+void drm_client_dev_unregister(struct drm_device *dev);
+void drm_client_dev_hotplug(struct drm_device *dev);
+void drm_client_dev_restore(struct drm_device *dev);
+
+/**
+ * struct drm_client_buffer - DRM client buffer
+ */
+struct drm_client_buffer {
+	/**
+	 * @client: DRM client
+	 */
+	struct drm_client_dev *client;
+
+	/**
+	 * @handle: Buffer handle
+	 */
+	u32 handle;
+
+	/**
+	 * @pitch: Buffer pitch
+	 */
+	u32 pitch;
+
+	/**
+	 * @gem: GEM object backing this buffer
+	 */
+	struct drm_gem_object *gem;
+
+	/**
+	 * @vaddr: Virtual address for the buffer
+	 */
+	void *vaddr;
+
+	/**
+	 * @fb: DRM framebuffer
+	 */
+	struct drm_framebuffer *fb;
+};
+
+struct drm_client_buffer *
+drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format);
+void drm_client_framebuffer_delete(struct drm_client_buffer *buffer);
+
+int drm_client_debugfs_init(struct drm_minor *minor);
+
+#endif
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index bf0f0f0786d3..97ea41dc678f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -290,6 +290,10 @@ struct drm_display_info {
 #define DRM_BUS_FLAG_DATA_MSB_TO_LSB	(1<<4)
 /* data is transmitted LSB to MSB on the bus */
 #define DRM_BUS_FLAG_DATA_LSB_TO_MSB	(1<<5)
+/* drive sync on pos. edge */
+#define DRM_BUS_FLAG_SYNC_POSEDGE	(1<<6)
+/* drive sync on neg. edge */
+#define DRM_BUS_FLAG_SYNC_NEGEDGE	(1<<7)
 
 	/**
 	 * @bus_flags: Additional information (like pixel signal polarity) for
@@ -374,12 +378,9 @@ struct drm_tv_connector_state {
 
 /**
  * struct drm_connector_state - mutable connector state
- * @connector: backpointer to the connector
- * @best_encoder: can be used by helpers and drivers to select the encoder
- * @state: backpointer to global drm_atomic_state
- * @tv: TV connector state
  */
 struct drm_connector_state {
+	/** @connector: backpointer to the connector */
 	struct drm_connector *connector;
 
 	/**
@@ -390,6 +391,13 @@ struct drm_connector_state {
 	 */
 	struct drm_crtc *crtc;
 
+	/**
+	 * @best_encoder:
+	 *
+	 * Used by the atomic helpers to select the encoder, through the
+	 * &drm_connector_helper_funcs.atomic_best_encoder or
+	 * &drm_connector_helper_funcs.best_encoder callbacks.
+	 */
 	struct drm_encoder *best_encoder;
 
 	/**
@@ -398,6 +406,7 @@ struct drm_connector_state {
 	 */
 	enum drm_link_status link_status;
 
+	/** @state: backpointer to global drm_atomic_state */
 	struct drm_atomic_state *state;
 
 	/**
@@ -407,6 +416,7 @@ struct drm_connector_state {
 	 */
 	struct drm_crtc_commit *commit;
 
+	/** @tv: TV connector state */
 	struct drm_tv_connector_state tv;
 
 	/**
@@ -551,8 +561,7 @@ struct drm_connector_funcs {
 	 * received for this output connector->edid must be NULL.
 	 *
 	 * Drivers using the probe helpers should use
-	 * drm_helper_probe_single_connector_modes() or
-	 * drm_helper_probe_single_connector_modes_nomerge() to implement this
+	 * drm_helper_probe_single_connector_modes() to implement this
 	 * function.
 	 *
 	 * RETURNS:
@@ -763,45 +772,6 @@ struct drm_cmdline_mode {
 
 /**
  * struct drm_connector - central DRM connector control structure
- * @dev: parent DRM device
- * @kdev: kernel device for sysfs attributes
- * @attr: sysfs attributes
- * @head: list management
- * @base: base KMS object
- * @name: human readable name, can be overwritten by the driver
- * @connector_type: one of the DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
- * @connector_type_id: index into connector type enum
- * @interlace_allowed: can this connector handle interlaced modes?
- * @doublescan_allowed: can this connector handle doublescan?
- * @stereo_allowed: can this connector handle stereo modes?
- * @funcs: connector control functions
- * @edid_blob_ptr: DRM property containing EDID if present
- * @properties: property tracking for this connector
- * @dpms: current dpms state
- * @helper_private: mid-layer private data
- * @cmdline_mode: mode line parsed from the kernel cmdline for this connector
- * @force: a DRM_FORCE_<foo> state for forced mode sets
- * @override_edid: has the EDID been overwritten through debugfs for testing?
- * @encoder_ids: valid encoders for this connector
- * @eld: EDID-like data, if present
- * @latency_present: AV delay info from ELD, if found
- * @video_latency: video latency info from ELD, if found
- * @audio_latency: audio latency info from ELD, if found
- * @null_edid_counter: track sinks that give us all zeros for the EDID
- * @bad_edid_counter: track sinks that give us an EDID with invalid checksum
- * @edid_corrupt: indicates whether the last read EDID was corrupt
- * @debugfs_entry: debugfs directory for this connector
- * @has_tile: is this connector connected to a tiled monitor
- * @tile_group: tile group for the connected monitor
- * @tile_is_single_monitor: whether the tile is one monitor housing
- * @num_h_tile: number of horizontal tiles in the tile group
- * @num_v_tile: number of vertical tiles in the tile group
- * @tile_h_loc: horizontal location of this tile
- * @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.
- * @content_protection_property: Optional property to control content protection
  *
  * 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
@@ -809,13 +779,27 @@ struct drm_cmdline_mode {
  * span multiple monitors).
  */
 struct drm_connector {
+	/** @dev: parent DRM device */
 	struct drm_device *dev;
+	/** @kdev: kernel device for sysfs attributes */
 	struct device *kdev;
+	/** @attr: sysfs attributes */
 	struct device_attribute *attr;
+
+	/**
+	 * @head:
+	 *
+	 * List of all connectors on a @dev, linked from
+	 * &drm_mode_config.connector_list. Protected by
+	 * &drm_mode_config.connector_list_lock, but please only use
+	 * &drm_connector_list_iter to walk this list.
+	 */
 	struct list_head head;
 
+	/** @base: base KMS object */
 	struct drm_mode_object base;
 
+	/** @name: human readable name, can be overwritten by the driver */
 	char *name;
 
 	/**
@@ -833,10 +817,30 @@ struct drm_connector {
 	 */
 	unsigned index;
 
+	/**
+	 * @connector_type:
+	 * one of the DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
+	 */
 	int connector_type;
+	/** @connector_type_id: index into connector type enum */
 	int connector_type_id;
+	/**
+	 * @interlace_allowed:
+	 * Can this connector handle interlaced modes? Only used by
+	 * drm_helper_probe_single_connector_modes() for mode filtering.
+	 */
 	bool interlace_allowed;
+	/**
+	 * @doublescan_allowed:
+	 * Can this connector handle doublescan? Only used by
+	 * drm_helper_probe_single_connector_modes() for mode filtering.
+	 */
 	bool doublescan_allowed;
+	/**
+	 * @stereo_allowed:
+	 * Can this connector handle stereo modes? Only used by
+	 * drm_helper_probe_single_connector_modes() for mode filtering.
+	 */
 	bool stereo_allowed;
 
 	/**
@@ -885,45 +889,42 @@ struct drm_connector {
 	 * Protected by &drm_mode_config.mutex.
 	 */
 	struct drm_display_info display_info;
+
+	/** @funcs: connector control functions */
 	const struct drm_connector_funcs *funcs;
 
+	/**
+	 * @edid_blob_ptr: DRM property containing EDID if present. Protected by
+	 * &drm_mode_config.mutex. This should be updated only by calling
+	 * drm_connector_update_edid_property().
+	 */
 	struct drm_property_blob *edid_blob_ptr;
+
+	/** @properties: property tracking for this connector */
 	struct drm_object_properties properties;
 
+	/**
+	 * @scaling_mode_property: Optional atomic property to control the
+	 * upscaling. See drm_connector_attach_content_protection_property().
+	 */
 	struct drm_property *scaling_mode_property;
 
 	/**
 	 * @content_protection_property: DRM ENUM property for content
-	 * protection
+	 * protection. See drm_connector_attach_content_protection_property().
 	 */
 	struct drm_property *content_protection_property;
 
 	/**
 	 * @path_blob_ptr:
 	 *
-	 * DRM blob property data for the DP MST path property.
+	 * DRM blob property data for the DP MST path property. This should only
+	 * be updated by calling drm_connector_set_path_property().
 	 */
 	struct drm_property_blob *path_blob_ptr;
 
-	/**
-	 * @tile_blob_ptr:
-	 *
-	 * DRM blob property data for the tile property (used mostly by DP MST).
-	 * This is meant for screens which are driven through separate display
-	 * pipelines represented by &drm_crtc, which might not be running with
-	 * genlocked clocks. For tiled panels which are genlocked, like
-	 * dual-link LVDS or dual-link DSI, the driver should try to not expose
-	 * the tiling and virtualize both &drm_crtc and &drm_plane if needed.
-	 */
-	struct drm_property_blob *tile_blob_ptr;
-
-/* should we poll this connector for connects and disconnects */
-/* hot plug detectable */
 #define DRM_CONNECTOR_POLL_HPD (1 << 0)
-/* poll for connections */
 #define DRM_CONNECTOR_POLL_CONNECT (1 << 1)
-/* can cleanly poll for disconnections without flickering the screen */
-/* DACs should rarely do this without a lot of testing */
 #define DRM_CONNECTOR_POLL_DISCONNECT (1 << 2)
 
 	/**
@@ -940,25 +941,40 @@ struct drm_connector {
 	 *     Periodically poll the connector for connection.
 	 *
 	 * DRM_CONNECTOR_POLL_DISCONNECT
-	 *     Periodically poll the connector for disconnection.
+	 *     Periodically poll the connector for disconnection, without
+	 *     causing flickering even when the connector is in use. DACs should
+	 *     rarely do this without a lot of testing.
 	 *
 	 * Set to 0 for connectors that don't support connection status
 	 * discovery.
 	 */
 	uint8_t polled;
 
-	/* requested DPMS state */
+	/**
+	 * @dpms: Current dpms state. For legacy drivers the
+	 * &drm_connector_funcs.dpms callback must update this. For atomic
+	 * drivers, this is handled by the core atomic code, and drivers must
+	 * only take &drm_crtc_state.active into account.
+	 */
 	int dpms;
 
+	/** @helper_private: mid-layer private data */
 	const struct drm_connector_helper_funcs *helper_private;
 
-	/* forced on connector */
+	/** @cmdline_mode: mode line parsed from the kernel cmdline for this connector */
 	struct drm_cmdline_mode cmdline_mode;
+	/** @force: a DRM_FORCE_<foo> state for forced mode sets */
 	enum drm_connector_force force;
+	/** @override_edid: has the EDID been overwritten through debugfs for testing? */
 	bool override_edid;
 
 #define DRM_CONNECTOR_MAX_ENCODER 3
+	/**
+	 * @encoder_ids: Valid encoders for this connector. Please only use
+	 * drm_connector_for_each_possible_encoder() to enumerate these.
+	 */
 	uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
+
 	/**
 	 * @encoder: Currently bound encoder driving this connector, if any.
 	 * Only really meaningful for non-atomic drivers. Atomic drivers should
@@ -968,19 +984,37 @@ struct drm_connector {
 	struct drm_encoder *encoder;
 
 #define MAX_ELD_BYTES	128
-	/* EDID bits */
+	/** @eld: EDID-like data, if present */
 	uint8_t eld[MAX_ELD_BYTES];
+	/** @latency_present: AV delay info from ELD, if found */
 	bool latency_present[2];
-	int video_latency[2];	/* [0]: progressive, [1]: interlaced */
+	/**
+	 * @video_latency: Video latency info from ELD, if found.
+	 * [0]: progressive, [1]: interlaced
+	 */
+	int video_latency[2];
+	/**
+	 * @audio_latency: audio latency info from ELD, if found
+	 * [0]: progressive, [1]: interlaced
+	 */
 	int audio_latency[2];
-	int null_edid_counter; /* needed to workaround some HW bugs where we get all 0s */
+	/**
+	 * @null_edid_counter: track sinks that give us all zeros for the EDID.
+	 * Needed to workaround some HW bugs where we get all 0s
+	 */
+	int null_edid_counter;
+
+	/** @bad_edid_counter: track sinks that give us an EDID with invalid checksum */
 	unsigned bad_edid_counter;
 
-	/* Flag for raw EDID header corruption - used in Displayport
-	 * compliance testing - * Displayport Link CTS Core 1.2 rev1.1 4.2.2.6
+	/**
+	 * @edid_corrupt: Indicates whether the last read EDID was corrupt. Used
+	 * in Displayport compliance testing - Displayport Link CTS Core 1.2
+	 * rev1.1 4.2.2.6
 	 */
 	bool edid_corrupt;
 
+	/** @debugfs_entry: debugfs directory for this connector */
 	struct dentry *debugfs_entry;
 
 	/**
@@ -988,7 +1022,7 @@ struct drm_connector {
 	 *
 	 * Current atomic state for this connector.
 	 *
-	 * This is protected by @drm_mode_config.connection_mutex. Note that
+	 * This is protected by &drm_mode_config.connection_mutex. Note that
 	 * nonblocking atomic commits access the current connector state without
 	 * taking locks. Either by going through the &struct drm_atomic_state
 	 * pointers, see for_each_oldnew_connector_in_state(),
@@ -999,19 +1033,44 @@ struct drm_connector {
 	 */
 	struct drm_connector_state *state;
 
-	/* DisplayID bits */
+	/* DisplayID bits. FIXME: Extract into a substruct? */
+
+	/**
+	 * @tile_blob_ptr:
+	 *
+	 * DRM blob property data for the tile property (used mostly by DP MST).
+	 * This is meant for screens which are driven through separate display
+	 * pipelines represented by &drm_crtc, which might not be running with
+	 * genlocked clocks. For tiled panels which are genlocked, like
+	 * dual-link LVDS or dual-link DSI, the driver should try to not expose
+	 * the tiling and virtualize both &drm_crtc and &drm_plane if needed.
+	 *
+	 * This should only be updated by calling
+	 * drm_connector_set_tile_property().
+	 */
+	struct drm_property_blob *tile_blob_ptr;
+
+	/** @has_tile: is this connector connected to a tiled monitor */
 	bool has_tile;
+	/** @tile_group: tile group for the connected monitor */
 	struct drm_tile_group *tile_group;
+	/** @tile_is_single_monitor: whether the tile is one monitor housing */
 	bool tile_is_single_monitor;
 
+	/** @num_h_tile: number of horizontal tiles in the tile group */
+	/** @num_v_tile: number of vertical tiles in the tile group */
 	uint8_t num_h_tile, num_v_tile;
+	/** @tile_h_loc: horizontal location of this tile */
+	/** @tile_v_loc: vertical location of this tile */
 	uint8_t tile_h_loc, tile_v_loc;
+	/** @tile_h_size: horizontal size of this tile. */
+	/** @tile_v_size: vertical size of this tile. */
 	uint16_t tile_h_size, tile_v_size;
 
 	/**
 	 * @free_node:
 	 *
-	 * List used only by &drm_connector_iter to be able to clean up a
+	 * List used only by &drm_connector_list_iter to be able to clean up a
 	 * connector from any context, in conjunction with
 	 * &drm_mode_config.connector_free_work.
 	 */
@@ -1026,7 +1085,7 @@ int drm_connector_init(struct drm_device *dev,
 		       int connector_type);
 int drm_connector_register(struct drm_connector *connector);
 void drm_connector_unregister(struct drm_connector *connector);
-int drm_mode_connector_attach_encoder(struct drm_connector *connector,
+int drm_connector_attach_encoder(struct drm_connector *connector,
 				      struct drm_encoder *encoder);
 
 void drm_connector_cleanup(struct drm_connector *connector);
@@ -1132,13 +1191,13 @@ void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
 
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
 
-int drm_mode_connector_set_path_property(struct drm_connector *connector,
-					 const char *path);
-int drm_mode_connector_set_tile_property(struct drm_connector *connector);
-int drm_mode_connector_update_edid_property(struct drm_connector *connector,
-					    const struct edid *edid);
-void drm_mode_connector_set_link_status_property(struct drm_connector *connector,
-						 uint64_t link_status);
+int drm_connector_set_path_property(struct drm_connector *connector,
+				    const char *path);
+int drm_connector_set_tile_property(struct drm_connector *connector);
+int drm_connector_update_edid_property(struct drm_connector *connector,
+				       const struct edid *edid);
+void drm_connector_set_link_status_property(struct drm_connector *connector,
+					    uint64_t link_status);
 int drm_connector_init_panel_orientation_property(
 	struct drm_connector *connector, int width, int height);
 
@@ -1187,6 +1246,9 @@ struct drm_connector *
 drm_connector_list_iter_next(struct drm_connector_list_iter *iter);
 void drm_connector_list_iter_end(struct drm_connector_list_iter *iter);
 
+bool drm_connector_has_possible_encoder(struct drm_connector *connector,
+					struct drm_encoder *encoder);
+
 /**
  * drm_for_each_connector_iter - connector_list iterator macro
  * @connector: &struct drm_connector pointer used as cursor
@@ -1199,4 +1261,17 @@ void drm_connector_list_iter_end(struct drm_connector_list_iter *iter);
 #define drm_for_each_connector_iter(connector, iter) \
 	while ((connector = drm_connector_list_iter_next(iter)))
 
+/**
+ * drm_connector_for_each_possible_encoder - iterate connector's possible encoders
+ * @connector: &struct drm_connector pointer
+ * @encoder: &struct drm_encoder pointer used as cursor
+ * @__i: int iteration cursor, for macro-internal use
+ */
+#define drm_connector_for_each_possible_encoder(connector, encoder, __i) \
+	for ((__i) = 0; (__i) < ARRAY_SIZE((connector)->encoder_ids) && \
+		     (connector)->encoder_ids[(__i)] != 0; (__i)++) \
+		for_each_if((encoder) = \
+			    drm_encoder_find((connector)->dev, NULL, \
+					     (connector)->encoder_ids[(__i)])) \
+
 #endif
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 23eddbccab10..92e7fc7f05a4 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -77,21 +77,6 @@ struct drm_plane_helper_funcs;
 
 /**
  * struct drm_crtc_state - mutable CRTC state
- * @crtc: backpointer to the CRTC
- * @enable: whether the CRTC should be enabled, gates all other state
- * @active: whether the CRTC is actively displaying (used for DPMS)
- * @planes_changed: planes on this crtc are updated
- * @mode_changed: @mode or @enable has been changed
- * @active_changed: @active has been toggled.
- * @connectors_changed: connectors to this crtc have been updated
- * @zpos_changed: zpos values of planes on this crtc have been updated
- * @color_mgmt_changed: color management properties have changed (degamma or
- *	gamma LUT or CSC matrix)
- * @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
- * @mode_blob: &drm_property_blob for @mode
- * @state: backpointer to global drm_atomic_state
  *
  * Note that the distinction between @enable and @active is rather subtile:
  * Flipping @active while @enable is set without changing anything else may
@@ -102,31 +87,127 @@ struct drm_plane_helper_funcs;
  *
  * The three booleans active_changed, connectors_changed and mode_changed are
  * intended to indicate whether a full modeset is needed, rather than strictly
- * describing what has changed in a commit.
- * See also: drm_atomic_crtc_needs_modeset()
+ * describing what has changed in a commit. See also:
+ * drm_atomic_crtc_needs_modeset()
+ *
+ * WARNING: Transitional helpers (like drm_helper_crtc_mode_set() or
+ * drm_helper_crtc_mode_set_base()) do not maintain many of the derived control
+ * state like @plane_mask so drivers not converted over to atomic helpers should
+ * not rely on these being accurate!
  */
 struct drm_crtc_state {
+	/** @crtc: backpointer to the CRTC */
 	struct drm_crtc *crtc;
 
+	/**
+	 * @enable: Whether the CRTC should be enabled, gates all other state.
+	 * This controls reservations of shared resources. Actual hardware state
+	 * is controlled by @active.
+	 */
 	bool enable;
+
+	/**
+	 * @active: Whether the CRTC is actively displaying (used for DPMS).
+	 * Implies that @enable is set. The driver must not release any shared
+	 * resources if @active is set to false but @enable still true, because
+	 * userspace expects that a DPMS ON always succeeds.
+	 *
+	 * Hence drivers must not consult @active in their various
+	 * &drm_mode_config_funcs.atomic_check callback to reject an atomic
+	 * commit. They can consult it to aid in the computation of derived
+	 * hardware state, since even in the DPMS OFF state the display hardware
+	 * should be as much powered down as when the CRTC is completely
+	 * disabled through setting @enable to false.
+	 */
 	bool active;
 
-	/* computed state bits used by helpers and drivers */
+	/**
+	 * @planes_changed: Planes on this crtc are updated. Used by the atomic
+	 * helpers and drivers to steer the atomic commit control flow.
+	 */
 	bool planes_changed : 1;
+
+	/**
+	 * @mode_changed: @mode or @enable has been changed. Used by the atomic
+	 * helpers and drivers to steer the atomic commit control flow. See also
+	 * drm_atomic_crtc_needs_modeset().
+	 *
+	 * Drivers are supposed to set this for any CRTC state changes that
+	 * require a full modeset. They can also reset it to false if e.g. a
+	 * @mode change can be done without a full modeset by only changing
+	 * scaler settings.
+	 */
 	bool mode_changed : 1;
+
+	/**
+	 * @active_changed: @active has been toggled. Used by the atomic
+	 * helpers and drivers to steer the atomic commit control flow. See also
+	 * drm_atomic_crtc_needs_modeset().
+	 */
 	bool active_changed : 1;
+
+	/**
+	 * @connectors_changed: Connectors to this crtc have been updated,
+	 * either in their state or routing. Used by the atomic
+	 * helpers and drivers to steer the atomic commit control flow. See also
+	 * drm_atomic_crtc_needs_modeset().
+	 *
+	 * Drivers are supposed to set this as-needed from their own atomic
+	 * check code, e.g. from &drm_encoder_helper_funcs.atomic_check
+	 */
 	bool connectors_changed : 1;
+	/**
+	 * @zpos_changed: zpos values of planes on this crtc have been updated.
+	 * Used by the atomic helpers and drivers to steer the atomic commit
+	 * control flow.
+	 */
 	bool zpos_changed : 1;
+	/**
+	 * @color_mgmt_changed: Color management properties have changed
+	 * (@gamma_lut, @degamma_lut or @ctm). Used by the atomic helpers and
+	 * drivers to steer the atomic commit control flow.
+	 */
 	bool color_mgmt_changed : 1;
 
-	/* attached planes bitmask:
-	 * WARNING: transitional helpers do not maintain plane_mask so
-	 * drivers not converted over to atomic helpers should not rely
-	 * on plane_mask being accurate!
+	/**
+	 * @no_vblank:
+	 *
+	 * Reflects the ability of a CRTC to send VBLANK events. This state
+	 * usually depends on the pipeline configuration, and the main usuage
+	 * is CRTCs feeding a writeback connector operating in oneshot mode.
+	 * In this case the VBLANK event is only generated when a job is queued
+	 * to the writeback connector, and we want the core to fake VBLANK
+	 * events when this part of the pipeline hasn't changed but others had
+	 * or when the CRTC and connectors are being disabled.
+	 *
+	 * __drm_atomic_helper_crtc_duplicate_state() will not reset the value
+	 * from the current state, the CRTC driver is then responsible for
+	 * updating this field when needed.
+	 *
+	 * Note that the combination of &drm_crtc_state.event == NULL and
+	 * &drm_crtc_state.no_blank == true is valid and usually used when the
+	 * writeback connector attached to the CRTC has a new job queued. In
+	 * this case the driver will send the VBLANK event on its own when the
+	 * writeback job is complete.
+	 */
+	bool no_vblank : 1;
+
+	/**
+	 * @plane_mask: Bitmask of drm_plane_mask(plane) of planes attached to
+	 * this CRTC.
 	 */
 	u32 plane_mask;
 
+	/**
+	 * @connector_mask: Bitmask of drm_connector_mask(connector) of
+	 * connectors attached to this CRTC.
+	 */
 	u32 connector_mask;
+
+	/**
+	 * @encoder_mask: Bitmask of drm_encoder_mask(encoder) of encoders
+	 * attached to this CRTC.
+	 */
 	u32 encoder_mask;
 
 	/**
@@ -136,7 +217,7 @@ struct drm_crtc_state {
 	 * differences between the mode requested by userspace in @mode and what
 	 * is actually programmed into the hardware.
 	 *
-	 * For drivers using drm_bridge, this stores hardware display timings
+	 * For drivers using &drm_bridge, this stores hardware display timings
 	 * used between the CRTC and the first bridge. For other drivers, the
 	 * meaning of the adjusted_mode field is purely driver implementation
 	 * defined information, and will usually be used to store the hardware
@@ -161,7 +242,10 @@ struct drm_crtc_state {
 	 */
 	struct drm_display_mode mode;
 
-	/* blob property to expose current mode to atomic userspace */
+	/**
+	 * @mode_blob: &drm_property_blob for @mode, for exposing the mode to
+	 * atomic userspace.
+	 */
 	struct drm_property_blob *mode_blob;
 
 	/**
@@ -265,6 +349,7 @@ struct drm_crtc_state {
 	 */
 	struct drm_crtc_commit *commit;
 
+	/** @state: backpointer to global drm_atomic_state */
 	struct drm_atomic_state *state;
 };
 
@@ -724,35 +809,25 @@ struct drm_crtc_funcs {
 
 /**
  * struct drm_crtc - central CRTC control structure
- * @dev: parent DRM device
- * @port: OF node used by drm_of_find_possible_crtcs()
- * @head: list management
- * @name: human readable name, can be overwritten by the driver
- * @mutex: per-CRTC locking
- * @base: base KMS object for ID tracking etc.
- * @primary: primary plane for this CRTC
- * @cursor: cursor plane for this CRTC
- * @cursor_x: current x position of the cursor, used for universal cursor planes
- * @cursor_y: current y position of the cursor, used for universal cursor planes
- * @enabled: is this CRTC enabled?
- * @mode: current mode timings
- * @hwmode: mode timings as programmed to hw regs
- * @x: x position on screen
- * @y: y position on screen
- * @funcs: CRTC control functions
- * @gamma_size: size of gamma ramp
- * @gamma_store: gamma ramp values
- * @helper_private: mid-layer private data
- * @properties: property tracking for this CRTC
  *
  * Each CRTC may have one or more connectors associated with it.  This structure
  * allows the CRTC to be controlled.
  */
 struct drm_crtc {
+	/** @dev: parent DRM device */
 	struct drm_device *dev;
+	/** @port: OF node used by drm_of_find_possible_crtcs(). */
 	struct device_node *port;
+	/**
+	 * @head:
+	 *
+	 * List of all CRTCs on @dev, linked from &drm_mode_config.crtc_list.
+	 * Invariant over the lifetime of @dev and therefore does not need
+	 * locking.
+	 */
 	struct list_head head;
 
+	/** @name: human readable name, can be overwritten by the driver */
 	char *name;
 
 	/**
@@ -767,10 +842,25 @@ struct drm_crtc {
 	 */
 	struct drm_modeset_lock mutex;
 
+	/** @base: base KMS object for ID tracking etc. */
 	struct drm_mode_object base;
 
-	/* primary and cursor planes for CRTC */
+	/**
+	 * @primary:
+	 * Primary plane for this CRTC. Note that this is only
+	 * relevant for legacy IOCTL, it specifies the plane implicitly used by
+	 * the SETCRTC and PAGE_FLIP IOCTLs. It does not have any significance
+	 * beyond that.
+	 */
 	struct drm_plane *primary;
+
+	/**
+	 * @cursor:
+	 * Cursor plane for this CRTC. Note that this is only relevant for
+	 * legacy IOCTL, it specifies the plane implicitly used by the SETCURSOR
+	 * and SETCURSOR2 IOCTLs. It does not have any significance
+	 * beyond that.
+	 */
 	struct drm_plane *cursor;
 
 	/**
@@ -779,30 +869,94 @@ struct drm_crtc {
 	 */
 	unsigned index;
 
-	/* position of cursor plane on crtc */
+	/**
+	 * @cursor_x: Current x position of the cursor, used for universal
+	 * cursor planes because the SETCURSOR IOCTL only can update the
+	 * framebuffer without supplying the coordinates. Drivers should not use
+	 * this directly, atomic drivers should look at &drm_plane_state.crtc_x
+	 * of the cursor plane instead.
+	 */
 	int cursor_x;
+	/**
+	 * @cursor_y: Current y position of the cursor, used for universal
+	 * cursor planes because the SETCURSOR IOCTL only can update the
+	 * framebuffer without supplying the coordinates. Drivers should not use
+	 * this directly, atomic drivers should look at &drm_plane_state.crtc_y
+	 * of the cursor plane instead.
+	 */
 	int cursor_y;
 
+	/**
+	 * @enabled:
+	 *
+	 * Is this CRTC enabled? Should only be used by legacy drivers, atomic
+	 * drivers should instead consult &drm_crtc_state.enable and
+	 * &drm_crtc_state.active. Atomic drivers can update this by calling
+	 * drm_atomic_helper_update_legacy_modeset_state().
+	 */
 	bool enabled;
 
-	/* Requested mode from modesetting. */
+	/**
+	 * @mode:
+	 *
+	 * Current mode timings. Should only be used by legacy drivers, atomic
+	 * drivers should instead consult &drm_crtc_state.mode. Atomic drivers
+	 * can update this by calling
+	 * drm_atomic_helper_update_legacy_modeset_state().
+	 */
 	struct drm_display_mode mode;
 
-	/* Programmed mode in hw, after adjustments for encoders,
-	 * crtc, panel scaling etc. Needed for timestamping etc.
+	/**
+	 * @hwmode:
+	 *
+	 * Programmed mode in hw, after adjustments for encoders, crtc, panel
+	 * scaling etc. Should only be used by legacy drivers, for high
+	 * precision vblank timestamps in
+	 * drm_calc_vbltimestamp_from_scanoutpos().
+	 *
+	 * Note that atomic drivers should not use this, but instead use
+	 * &drm_crtc_state.adjusted_mode. And for high-precision timestamps
+	 * drm_calc_vbltimestamp_from_scanoutpos() used &drm_vblank_crtc.hwmode,
+	 * which is filled out by calling drm_calc_timestamping_constants().
 	 */
 	struct drm_display_mode hwmode;
 
-	int x, y;
+	/**
+	 * @x:
+	 * x position on screen. Should only be used by legacy drivers, atomic
+	 * drivers should look at &drm_plane_state.crtc_x of the primary plane
+	 * instead. Updated by calling
+	 * drm_atomic_helper_update_legacy_modeset_state().
+	 */
+	int x;
+	/**
+	 * @y:
+	 * y position on screen. Should only be used by legacy drivers, atomic
+	 * drivers should look at &drm_plane_state.crtc_y of the primary plane
+	 * instead. Updated by calling
+	 * drm_atomic_helper_update_legacy_modeset_state().
+	 */
+	int y;
+
+	/** @funcs: CRTC control functions */
 	const struct drm_crtc_funcs *funcs;
 
-	/* Legacy FB CRTC gamma size for reporting to userspace */
+	/**
+	 * @gamma_size: Size of legacy gamma ramp reported to userspace. Set up
+	 * by calling drm_mode_crtc_set_gamma_size().
+	 */
 	uint32_t gamma_size;
+
+	/**
+	 * @gamma_store: Gamma ramp values used by the legacy SETGAMMA and
+	 * GETGAMMA IOCTls. Set up by calling drm_mode_crtc_set_gamma_size().
+	 */
 	uint16_t *gamma_store;
 
-	/* if you are using the helper */
+	/** @helper_private: mid-layer private data */
 	const struct drm_crtc_helper_funcs *helper_private;
 
+	/** @properties: property tracking for this CRTC */
 	struct drm_object_properties properties;
 
 	/**
@@ -872,7 +1026,6 @@ struct drm_crtc {
 	 *
 	 * spinlock to protect the fences in the fence_context.
 	 */
-
 	spinlock_t fence_lock;
 	/**
 	 * @fence_seqno:
@@ -942,8 +1095,8 @@ static inline unsigned int drm_crtc_index(const struct drm_crtc *crtc)
  * drm_crtc_mask - find the mask of a registered CRTC
  * @crtc: CRTC to find mask for
  *
- * Given a registered CRTC, return the mask bit of that CRTC for an
- * encoder's possible_crtcs field.
+ * Given a registered CRTC, return the mask bit of that CRTC for the
+ * &drm_encoder.possible_crtcs and &drm_plane.possible_crtcs fields.
  */
 static inline uint32_t drm_crtc_mask(const struct drm_crtc *crtc)
 {
diff --git a/include/drm/drm_debugfs_crc.h b/include/drm/drm_debugfs_crc.h
index 7d63b1d4adb9..b225eeb30d05 100644
--- a/include/drm/drm_debugfs_crc.h
+++ b/include/drm/drm_debugfs_crc.h
@@ -43,6 +43,7 @@ struct drm_crtc_crc_entry {
  * @lock: protects the fields in this struct
  * @source: name of the currently configured source of CRCs
  * @opened: whether userspace has opened the data file for reading
+ * @overflow: whether an overflow occured.
  * @entries: array of entries, with size of %DRM_CRC_ENTRIES_NR
  * @head: head of circular queue
  * @tail: tail of circular queue
@@ -52,7 +53,7 @@ struct drm_crtc_crc_entry {
 struct drm_crtc_crc {
 	spinlock_t lock;
 	const char *source;
-	bool opened;
+	bool opened, overflow;
 	struct drm_crtc_crc_entry *entries;
 	int head, tail;
 	size_t values_cnt;
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 858ba19a3e29..f9c6e0e3aec7 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -74,6 +74,27 @@ struct drm_device {
 	struct mutex filelist_mutex;
 	struct list_head filelist;
 
+	/**
+	 * @filelist_internal:
+	 *
+	 * List of open DRM files for in-kernel clients. Protected by @filelist_mutex.
+	 */
+	struct list_head filelist_internal;
+
+	/**
+	 * @clientlist_mutex:
+	 *
+	 * Protects @clientlist access.
+	 */
+	struct mutex clientlist_mutex;
+
+	/**
+	 * @clientlist:
+	 *
+	 * List of in-kernel clients. Protected by @clientlist_mutex.
+	 */
+	struct list_head clientlist;
+
 	/** \name Memory management */
 	/*@{ */
 	struct list_head maplist;	/**< Linked list of regions */
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index c01564991a9f..05cc31b5db16 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1078,6 +1078,25 @@ struct drm_dp_aux_msg {
 	size_t size;
 };
 
+struct cec_adapter;
+struct edid;
+
+/**
+ * struct drm_dp_aux_cec - DisplayPort CEC-Tunneling-over-AUX
+ * @lock: mutex protecting this struct
+ * @adap: the CEC adapter for CEC-Tunneling-over-AUX support.
+ * @name: name of the CEC adapter
+ * @parent: parent device of the CEC adapter
+ * @unregister_work: unregister the CEC adapter
+ */
+struct drm_dp_aux_cec {
+	struct mutex lock;
+	struct cec_adapter *adap;
+	const char *name;
+	struct device *parent;
+	struct delayed_work unregister_work;
+};
+
 /**
  * struct drm_dp_aux - DisplayPort AUX channel
  * @name: user-visible name of this AUX channel and the I2C-over-AUX adapter
@@ -1136,6 +1155,10 @@ struct drm_dp_aux {
 	 * @i2c_defer_count: Counts I2C DEFERs, used for DP validation.
 	 */
 	unsigned i2c_defer_count;
+	/**
+	 * @cec: struct containing fields used for CEC-Tunneling-over-AUX.
+	 */
+	struct drm_dp_aux_cec cec;
 };
 
 ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
@@ -1258,4 +1281,37 @@ drm_dp_has_quirk(const struct drm_dp_desc *desc, enum drm_dp_quirk quirk)
 	return desc->quirks & BIT(quirk);
 }
 
+#ifdef CONFIG_DRM_DP_CEC
+void drm_dp_cec_irq(struct drm_dp_aux *aux);
+void drm_dp_cec_register_connector(struct drm_dp_aux *aux, const char *name,
+				   struct device *parent);
+void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux);
+void drm_dp_cec_set_edid(struct drm_dp_aux *aux, const struct edid *edid);
+void drm_dp_cec_unset_edid(struct drm_dp_aux *aux);
+#else
+static inline void drm_dp_cec_irq(struct drm_dp_aux *aux)
+{
+}
+
+static inline void drm_dp_cec_register_connector(struct drm_dp_aux *aux,
+						 const char *name,
+						 struct device *parent)
+{
+}
+
+static inline void drm_dp_cec_unregister_connector(struct drm_dp_aux *aux)
+{
+}
+
+static inline void drm_dp_cec_set_edid(struct drm_dp_aux *aux,
+				       const struct edid *edid)
+{
+}
+
+static inline void drm_dp_cec_unset_edid(struct drm_dp_aux *aux)
+{
+}
+
+#endif
+
 #endif /* _DRM_DP_HELPER_H_ */
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 7e545f5f94d3..46a8009784df 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -649,6 +649,35 @@ static inline bool drm_dev_is_unplugged(struct drm_device *dev)
 	return true;
 }
 
+/**
+ * drm_core_check_feature - check driver feature flags
+ * @dev: DRM device to check
+ * @feature: feature flag
+ *
+ * This checks @dev for driver features, see &drm_driver.driver_features and the
+ * various DRIVER_\* flags.
+ *
+ * Returns true if the @feature is supported, false otherwise.
+ */
+static inline bool drm_core_check_feature(struct drm_device *dev, int feature)
+{
+	return dev->driver->driver_features & feature;
+}
+
+/**
+ * drm_drv_uses_atomic_modeset - check if the driver implements
+ * atomic_commit()
+ * @dev: DRM device
+ *
+ * This check is useful if drivers do not have DRIVER_ATOMIC set but
+ * have atomic modesetting internally implemented.
+ */
+static inline bool drm_drv_uses_atomic_modeset(struct drm_device *dev)
+{
+	return drm_core_check_feature(dev, DRIVER_ATOMIC) ||
+		dev->mode_config.funcs->atomic_commit != NULL;
+}
+
 
 int drm_dev_set_unique(struct drm_device *dev, const char *name);
 
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h
index d532f88a8d55..96e26e3b9a0c 100644
--- a/include/drm/drm_fb_cma_helper.h
+++ b/include/drm/drm_fb_cma_helper.h
@@ -16,16 +16,10 @@ struct drm_mode_fb_cmd2;
 struct drm_plane;
 struct drm_plane_state;
 
-int drm_fb_cma_fbdev_init_with_funcs(struct drm_device *dev,
-	unsigned int preferred_bpp, unsigned int max_conn_count,
-	const struct drm_framebuffer_funcs *funcs);
 int drm_fb_cma_fbdev_init(struct drm_device *dev, unsigned int preferred_bpp,
 			  unsigned int max_conn_count);
 void drm_fb_cma_fbdev_fini(struct drm_device *dev);
 
-struct drm_fbdev_cma *drm_fbdev_cma_init_with_funcs(struct drm_device *dev,
-	unsigned int preferred_bpp, unsigned int max_conn_count,
-	const struct drm_framebuffer_funcs *funcs);
 struct drm_fbdev_cma *drm_fbdev_cma_init(struct drm_device *dev,
 	unsigned int preferred_bpp, unsigned int max_conn_count);
 void drm_fbdev_cma_fini(struct drm_fbdev_cma *fbdev_cma);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index b069433e7fc1..5db08c8f1d25 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -32,6 +32,7 @@
 
 struct drm_fb_helper;
 
+#include <drm/drm_client.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_device.h>
 #include <linux/kgdb.h>
@@ -154,6 +155,20 @@ struct drm_fb_helper_connector {
  * operations.
  */
 struct drm_fb_helper {
+	/**
+	 * @client:
+	 *
+	 * DRM client used by the generic fbdev emulation.
+	 */
+	struct drm_client_dev client;
+
+	/**
+	 * @buffer:
+	 *
+	 * Framebuffer used by the generic fbdev emulation.
+	 */
+	struct drm_client_buffer *buffer;
+
 	struct drm_framebuffer *fb;
 	struct drm_device *dev;
 	int crtc_count;
@@ -234,6 +249,12 @@ struct drm_fb_helper {
 	int preferred_bpp;
 };
 
+static inline struct drm_fb_helper *
+drm_fb_helper_from_client(struct drm_client_dev *client)
+{
+	return container_of(client, struct drm_fb_helper, client);
+}
+
 /**
  * define DRM_FB_HELPER_DEFAULT_OPS - helper define for drm drivers
  *
@@ -330,6 +351,10 @@ void drm_fb_helper_fbdev_teardown(struct drm_device *dev);
 
 void drm_fb_helper_lastclose(struct drm_device *dev);
 void drm_fb_helper_output_poll_changed(struct drm_device *dev);
+
+int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
+				struct drm_fb_helper_surface_size *sizes);
+int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp);
 #else
 static inline void drm_fb_helper_prepare(struct drm_device *dev,
 					struct drm_fb_helper *helper,
@@ -564,6 +589,19 @@ static inline void drm_fb_helper_output_poll_changed(struct drm_device *dev)
 {
 }
 
+static inline int
+drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper,
+			    struct drm_fb_helper_surface_size *sizes)
+{
+	return 0;
+}
+
+static inline int
+drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp)
+{
+	return 0;
+}
+
 #endif
 
 static inline int
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 3e86408dac9f..f9c15845f465 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -39,6 +39,7 @@ struct drm_mode_fb_cmd2;
  * @hsub: Horizontal chroma subsampling factor
  * @vsub: Vertical chroma subsampling factor
  * @has_alpha: Does the format embeds an alpha component?
+ * @is_yuv: Is it a YUV format?
  */
 struct drm_format_info {
 	u32 format;
@@ -48,6 +49,7 @@ struct drm_format_info {
 	u8 hsub;
 	u8 vsub;
 	bool has_alpha;
+	bool is_yuv;
 };
 
 /**
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index b159fe07fcf9..baded6514456 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -530,7 +530,7 @@ drm_mode_validate_ycbcr420(const struct drm_display_mode *mode,
 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);
+void drm_connector_list_update(struct drm_connector *connector);
 
 /* parsing cmdline modes */
 bool
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 3b289773297c..61142aa0ab23 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -785,7 +785,7 @@ struct drm_connector_helper_funcs {
 	 *
 	 * This function should fill in all modes currently valid for the sink
 	 * into the &drm_connector.probed_modes list. It should also update the
-	 * EDID property by calling drm_mode_connector_update_edid_property().
+	 * EDID property by calling drm_connector_update_edid_property().
 	 *
 	 * The usual way to implement this is to cache the EDID retrieved in the
 	 * probe callback somewhere in the driver-private connector structure.
@@ -980,11 +980,15 @@ struct drm_connector_helper_funcs {
 	 *
 	 * This hook is to be used by drivers implementing writeback connectors
 	 * that need a point when to commit the writeback job to the hardware.
+	 * The writeback_job to commit is available in
+	 * &drm_connector_state.writeback_job.
+	 *
+	 * This hook is optional.
 	 *
 	 * This callback is used by the atomic modeset helpers.
 	 */
 	void (*atomic_commit)(struct drm_connector *connector,
-			      struct drm_writeback_job *writeback_job);
+			      struct drm_connector_state *state);
 };
 
 /**
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 26a1b5fd8796..582a0ec0aa70 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -200,7 +200,7 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np);
 #else
 static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
 {
-	return NULL;
+	return ERR_PTR(-ENODEV);
 }
 #endif
 
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index cee9dfaaa740..8a152dc16ea5 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -34,31 +34,15 @@ struct drm_modeset_acquire_ctx;
 
 /**
  * struct drm_plane_state - mutable plane state
- * @plane: backpointer to the plane
- * @crtc_w: width of visible portion of plane on crtc
- * @crtc_h: height of visible portion of plane on crtc
- * @src_x: left position of visible portion of plane within
- *	plane (in 16.16)
- * @src_y: upper position of visible portion of plane within
- *	plane (in 16.16)
- * @src_w: width of visible portion of plane (in 16.16)
- * @src_h: height of visible portion of plane (in 16.16)
- * @alpha: opacity of the plane
- * @rotation: rotation of the plane
- * @zpos: priority of the given plane on crtc (optional)
- *	Note that multiple active planes on the same crtc can have an identical
- *	zpos value. The rule to solving the conflict is to compare the plane
- *	object IDs; the plane with a higher ID must be stacked on top of a
- *	plane with a lower ID.
- * @normalized_zpos: normalized value of zpos: unique, range from 0 to N-1
- *	where N is the number of active planes for given crtc. Note that
- *	the driver must set drm_mode_config.normalize_zpos or call
- *	drm_atomic_normalize_zpos() to update this before it can be trusted.
- * @src: clipped source coordinates of the plane (in 16.16)
- * @dst: clipped destination coordinates of the plane
- * @state: backpointer to global drm_atomic_state
+ *
+ * Please not that the destination coordinates @crtc_x, @crtc_y, @crtc_h and
+ * @crtc_w and the source coordinates @src_x, @src_y, @src_h and @src_w are the
+ * raw coordinates provided by userspace. Drivers should use
+ * drm_atomic_helper_check_plane_state() and only use the derived rectangles in
+ * @src and @dst to program the hardware.
  */
 struct drm_plane_state {
+	/** @plane: backpointer to the plane */
 	struct drm_plane *plane;
 
 	/**
@@ -87,7 +71,7 @@ struct drm_plane_state {
 	 * preserved.
 	 *
 	 * Drivers should store any implicit fence in this from their
-	 * &drm_plane_helper.prepare_fb callback. See drm_gem_fb_prepare_fb()
+	 * &drm_plane_helper_funcs.prepare_fb callback. See drm_gem_fb_prepare_fb()
 	 * and drm_gem_fb_simple_display_pipe_prepare_fb() for suitable helpers.
 	 */
 	struct dma_fence *fence;
@@ -108,20 +92,60 @@ struct drm_plane_state {
 	 */
 	int32_t crtc_y;
 
+	/** @crtc_w: width of visible portion of plane on crtc */
+	/** @crtc_h: height of visible portion of plane on crtc */
 	uint32_t crtc_w, crtc_h;
 
-	/* Source values are 16.16 fixed point */
-	uint32_t src_x, src_y;
+	/**
+	 * @src_x: left position of visible portion of plane within plane (in
+	 * 16.16 fixed point).
+	 */
+	uint32_t src_x;
+	/**
+	 * @src_y: upper position of visible portion of plane within plane (in
+	 * 16.16 fixed point).
+	 */
+	uint32_t src_y;
+	/** @src_w: width of visible portion of plane (in 16.16) */
+	/** @src_h: height of visible portion of plane (in 16.16) */
 	uint32_t src_h, src_w;
 
-	/* Plane opacity */
+	/**
+	 * @alpha:
+	 * Opacity of the plane with 0 as completely transparent and 0xffff as
+	 * completely opaque. See drm_plane_create_alpha_property() for more
+	 * details.
+	 */
 	u16 alpha;
 
-	/* Plane rotation */
+	/**
+	 * @rotation:
+	 * Rotation of the plane. See drm_plane_create_rotation_property() for
+	 * more details.
+	 */
 	unsigned int rotation;
 
-	/* Plane zpos */
+	/**
+	 * @zpos:
+	 * Priority of the given plane on crtc (optional).
+	 *
+	 * Note that multiple active planes on the same crtc can have an
+	 * identical zpos value. The rule to solving the conflict is to compare
+	 * the plane object IDs; the plane with a higher ID must be stacked on
+	 * top of a plane with a lower ID.
+	 *
+	 * See drm_plane_create_zpos_property() and
+	 * drm_plane_create_zpos_immutable_property() for more details.
+	 */
 	unsigned int zpos;
+
+	/**
+	 * @normalized_zpos:
+	 * Normalized value of zpos: unique, range from 0 to N-1 where N is the
+	 * number of active planes for given crtc. Note that the driver must set
+	 * &drm_mode_config.normalize_zpos or call drm_atomic_normalize_zpos() to
+	 * update this before it can be trusted.
+	 */
 	unsigned int normalized_zpos;
 
 	/**
@@ -138,7 +162,8 @@ struct drm_plane_state {
 	 */
 	enum drm_color_range color_range;
 
-	/* Clipped coordinates */
+	/** @src: clipped source coordinates of the plane (in 16.16) */
+	/** @dst: clipped destination coordinates of the plane */
 	struct drm_rect src, dst;
 
 	/**
@@ -157,6 +182,7 @@ struct drm_plane_state {
 	 */
 	struct drm_crtc_commit *commit;
 
+	/** @state: backpointer to global drm_atomic_state */
 	struct drm_atomic_state *state;
 };
 
@@ -499,30 +525,27 @@ enum drm_plane_type {
 
 /**
  * struct drm_plane - central DRM plane control structure
- * @dev: DRM device this plane belongs to
- * @head: for list management
- * @name: human readable name, can be overwritten by the driver
- * @base: base mode object
- * @possible_crtcs: pipes this plane can be bound to
- * @format_types: array of formats supported by this plane
- * @format_count: number of formats supported
- * @format_default: driver hasn't supplied supported formats for the plane
- * @modifiers: array of modifiers supported by this plane
- * @modifier_count: number of modifiers supported
- * @old_fb: Temporary tracking of the old fb while a modeset is ongoing. Used by
- * 	drm_mode_set_config_internal() to implement correct refcounting.
- * @funcs: helper functions
- * @properties: property tracking for this plane
- * @type: type of plane (overlay, primary, cursor)
- * @alpha_property: alpha property for this plane
- * @zpos_property: zpos property for this plane
- * @rotation_property: rotation property for this plane
- * @helper_private: mid-layer private data
+ *
+ * Planes represent the scanout hardware of a display block. They receive their
+ * input data from a &drm_framebuffer and feed it to a &drm_crtc. Planes control
+ * the color conversion, see `Plane Composition Properties`_ for more details,
+ * and are also involved in the color conversion of input pixels, see `Color
+ * Management Properties`_ for details on that.
  */
 struct drm_plane {
+	/** @dev: DRM device this plane belongs to */
 	struct drm_device *dev;
+
+	/**
+	 * @head:
+	 *
+	 * List of all planes on @dev, linked from &drm_mode_config.plane_list.
+	 * Invariant over the lifetime of @dev and therefore does not need
+	 * locking.
+	 */
 	struct list_head head;
 
+	/** @name: human readable name, can be overwritten by the driver */
 	char *name;
 
 	/**
@@ -536,35 +559,62 @@ struct drm_plane {
 	 */
 	struct drm_modeset_lock mutex;
 
+	/** @base: base mode object */
 	struct drm_mode_object base;
 
+	/**
+	 * @possible_crtcs: pipes this plane can be bound to constructed from
+	 * drm_crtc_mask()
+	 */
 	uint32_t possible_crtcs;
+	/** @format_types: array of formats supported by this plane */
 	uint32_t *format_types;
+	/** @format_count: Size of the array pointed at by @format_types. */
 	unsigned int format_count;
+	/**
+	 * @format_default: driver hasn't supplied supported formats for the
+	 * plane. Used by the drm_plane_init compatibility wrapper only.
+	 */
 	bool format_default;
 
+	/** @modifiers: array of modifiers supported by this plane */
 	uint64_t *modifiers;
+	/** @modifier_count: Size of the array pointed at by @modifier_count. */
 	unsigned int modifier_count;
 
 	/**
-	 * @crtc: Currently bound CRTC, only really meaningful for non-atomic
-	 * drivers.  Atomic drivers should instead check &drm_plane_state.crtc.
+	 * @crtc:
+	 *
+	 * Currently bound CRTC, only meaningful for non-atomic drivers. For
+	 * atomic drivers this is forced to be NULL, atomic drivers should
+	 * instead check &drm_plane_state.crtc.
 	 */
 	struct drm_crtc *crtc;
 
 	/**
-	 * @fb: Currently bound framebuffer, only really meaningful for
-	 * non-atomic drivers.  Atomic drivers should instead check
-	 * &drm_plane_state.fb.
+	 * @fb:
+	 *
+	 * Currently bound framebuffer, only meaningful for non-atomic drivers.
+	 * For atomic drivers this is forced to be NULL, atomic drivers should
+	 * instead check &drm_plane_state.fb.
 	 */
 	struct drm_framebuffer *fb;
 
+	/**
+	 * @old_fb:
+	 *
+	 * Temporary tracking of the old fb while a modeset is ongoing. Only
+	 * used by non-atomic drivers, forced to be NULL for atomic drivers.
+	 */
 	struct drm_framebuffer *old_fb;
 
+	/** @funcs: plane control functions */
 	const struct drm_plane_funcs *funcs;
 
+	/** @properties: property tracking for this plane */
 	struct drm_object_properties properties;
 
+	/** @type: Type of plane, see &enum drm_plane_type for details. */
 	enum drm_plane_type type;
 
 	/**
@@ -573,6 +623,7 @@ struct drm_plane {
 	 */
 	unsigned index;
 
+	/** @helper_private: mid-layer private data */
 	const struct drm_plane_helper_funcs *helper_private;
 
 	/**
@@ -590,8 +641,23 @@ struct drm_plane {
 	 */
 	struct drm_plane_state *state;
 
+	/**
+	 * @alpha_property:
+	 * Optional alpha property for this plane. See
+	 * drm_plane_create_alpha_property().
+	 */
 	struct drm_property *alpha_property;
+	/**
+	 * @zpos_property:
+	 * Optional zpos property for this plane. See
+	 * drm_plane_create_zpos_property().
+	 */
 	struct drm_property *zpos_property;
+	/**
+	 * @rotation_property:
+	 * Optional rotation property for this plane. See
+	 * drm_plane_create_rotation_property().
+	 */
 	struct drm_property *rotation_property;
 
 	/**
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index e1a46e9991cc..767c90b654c5 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -195,6 +195,7 @@ static inline struct drm_printer drm_debug_printer(const char *prefix)
 #define DRM_UT_VBL		0x20
 #define DRM_UT_STATE		0x40
 #define DRM_UT_LEASE		0x80
+#define DRM_UT_DP		0x100
 
 __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
@@ -307,6 +308,11 @@ void drm_err(const char *format, ...);
 #define DRM_DEBUG_LEASE(fmt, ...)					\
 	drm_dbg(DRM_UT_LEASE, fmt, ##__VA_ARGS__)
 
+#define	DRM_DEV_DEBUG_DP(dev, fmt, ...)					\
+	drm_dev_dbg(dev, DRM_UT_DP, fmt, ## __VA_ARGS__)
+#define DRM_DEBUG_DP(dev, fmt, ...)					\
+	drm_dbg(DRM_UT_DP, fmt, ## __VA_ARGS__)
+
 #define _DRM_DEV_DEFINE_DEBUG_RATELIMITED(dev, category, fmt, ...)	\
 ({									\
 	static DEFINE_RATELIMIT_STATE(_rs,				\
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 1d5c0b2a8956..c030f6ccab99 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -147,10 +147,10 @@ struct drm_property {
 	 *     properties are not exposed to legacy userspace.
 	 *
 	 * DRM_MODE_PROP_IMMUTABLE
-	 *     Set for properties where userspace cannot be changed by
+	 *     Set for properties whose values cannot be changed by
 	 *     userspace. The kernel is allowed to update the value of these
 	 *     properties. This is generally used to expose probe state to
-	 *     usersapce, e.g. the EDID, or the connector path property on DP
+	 *     userspace, e.g. the EDID, or the connector path property on DP
 	 *     MST sinks.
 	 */
 	uint32_t flags;
diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h
index 8758df94e9a0..c7987daeaed0 100644
--- a/include/drm/drm_vma_manager.h
+++ b/include/drm/drm_vma_manager.h
@@ -41,6 +41,7 @@ struct drm_vma_offset_node {
 	rwlock_t vm_lock;
 	struct drm_mm_node vm_node;
 	struct rb_root vm_files;
+	bool readonly:1;
 };
 
 struct drm_vma_offset_manager {
diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h
index a10fe556dfd4..23df9d463003 100644
--- a/include/drm/drm_writeback.h
+++ b/include/drm/drm_writeback.h
@@ -110,6 +110,12 @@ struct drm_writeback_job {
 	struct dma_fence *out_fence;
 };
 
+static inline struct drm_writeback_connector *
+drm_connector_to_writeback(struct drm_connector *connector)
+{
+	return container_of(connector, struct drm_writeback_connector, base);
+}
+
 int drm_writeback_connector_init(struct drm_device *dev,
 				 struct drm_writeback_connector *wb_connector,
 				 const struct drm_connector_funcs *con_funcs,
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index c9e5a6621b95..c44703f471b3 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -95,7 +95,9 @@ extern struct resource intel_graphics_stolen_res;
 #define    I845_TSEG_SIZE_512K	(2 << 1)
 #define    I845_TSEG_SIZE_1M	(3 << 1)
 
-#define INTEL_BSM 0x5c
+#define INTEL_BSM		0x5c
+#define INTEL_GEN11_BSM_DW0	0xc0
+#define INTEL_GEN11_BSM_DW1	0xc4
 #define   INTEL_BSM_MASK	(-(1u << 20))
 
 #endif				/* _I915_DRM_H_ */
diff --git a/include/drm/tinydrm/tinydrm.h b/include/drm/tinydrm/tinydrm.h
index 56e4a916b5e8..fe9827d0ca8a 100644
--- a/include/drm/tinydrm/tinydrm.h
+++ b/include/drm/tinydrm/tinydrm.h
@@ -16,16 +16,31 @@
 
 /**
  * struct tinydrm_device - tinydrm device
- * @drm: DRM device
- * @pipe: Display pipe structure
- * @dirty_lock: Serializes framebuffer flushing
- * @fb_funcs: Framebuffer functions used when creating framebuffers
  */
 struct tinydrm_device {
+	/**
+	 * @drm: DRM device
+	 */
 	struct drm_device *drm;
+
+	/**
+	 * @pipe: Display pipe structure
+	 */
 	struct drm_simple_display_pipe pipe;
+
+	/**
+	 * @dirty_lock: Serializes framebuffer flushing
+	 */
 	struct mutex dirty_lock;
+
+	/**
+	 * @fb_funcs: Framebuffer functions used when creating framebuffers
+	 */
 	const struct drm_framebuffer_funcs *fb_funcs;
+
+	/**
+	 * @fb_dirty: Framebuffer dirty callback
+	 */
 	int (*fb_dirty)(struct drm_framebuffer *framebuffer,
 			struct drm_file *file_priv, unsigned flags,
 			unsigned color, struct drm_clip_rect *clips,