summaryrefslogtreecommitdiff
path: root/include/drm
diff options
context:
space:
mode:
authorMatthew Brost <matthew.brost@intel.com>2026-03-12 07:17:56 -0700
committerMatthew Brost <matthew.brost@intel.com>2026-03-12 07:23:23 -0700
commit42d3b66d4cdbacfc9d120d2301b8de89cc29a914 (patch)
tree999800b4737152481da268f2450088ab2f557115 /include/drm
parent635e3eba1ebcd5b92856e975e1d3859b487dc88b (diff)
parent58351f46de26bcc4403f9972f7aed430d15cbd03 (diff)
downloadlinux-next-42d3b66d4cdbacfc9d120d2301b8de89cc29a914.tar.gz
linux-next-42d3b66d4cdbacfc9d120d2301b8de89cc29a914.zip
Merge drm/drm-next into drm-xe-next
Backmerging to bring in 7.00-rc3. Important ahead GPU SVM merging THP support. Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Diffstat (limited to 'include/drm')
-rw-r--r--include/drm/bridge/dw_dp.h7
-rw-r--r--include/drm/bridge/dw_hdmi_qp.h1
-rw-r--r--include/drm/bridge/inno_hdmi.h35
-rw-r--r--include/drm/bridge/samsung-dsim.h1
-rw-r--r--include/drm/display/drm_dp.h2
-rw-r--r--include/drm/display/drm_dp_helper.h57
-rw-r--r--include/drm/drm_atomic.h60
-rw-r--r--include/drm/drm_atomic_helper.h22
-rw-r--r--include/drm/drm_atomic_state_helper.h3
-rw-r--r--include/drm/drm_bridge.h393
-rw-r--r--include/drm/drm_buddy.h163
-rw-r--r--include/drm/drm_client.h3
-rw-r--r--include/drm/drm_colorop.h32
-rw-r--r--include/drm/drm_connector.h106
-rw-r--r--include/drm/drm_fb_helper.h105
-rw-r--r--include/drm/drm_gem_shmem_helper.h11
-rw-r--r--include/drm/drm_gpuvm.h12
-rw-r--r--include/drm/drm_mode_config.h4
-rw-r--r--include/drm/drm_mode_object.h3
-rw-r--r--include/drm/drm_of.h6
-rw-r--r--include/drm/drm_property.h1
-rw-r--r--include/drm/intel/display_parent_interface.h17
-rw-r--r--include/drm/intel/intel_lb_mei_interface.h3
23 files changed, 490 insertions, 557 deletions
diff --git a/include/drm/bridge/dw_dp.h b/include/drm/bridge/dw_dp.h
index d05df49fd884..25363541e69d 100644
--- a/include/drm/bridge/dw_dp.h
+++ b/include/drm/bridge/dw_dp.h
@@ -11,8 +11,15 @@
struct drm_encoder;
struct dw_dp;
+enum {
+ DW_DP_MP_SINGLE_PIXEL,
+ DW_DP_MP_DUAL_PIXEL,
+ DW_DP_MP_QUAD_PIXEL,
+};
+
struct dw_dp_plat_data {
u32 max_link_rate;
+ u8 pixel_mode;
};
struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
diff --git a/include/drm/bridge/dw_hdmi_qp.h b/include/drm/bridge/dw_hdmi_qp.h
index 3f461f6b9bbf..3af12f82da2c 100644
--- a/include/drm/bridge/dw_hdmi_qp.h
+++ b/include/drm/bridge/dw_hdmi_qp.h
@@ -34,5 +34,6 @@ struct dw_hdmi_qp_plat_data {
struct dw_hdmi_qp *dw_hdmi_qp_bind(struct platform_device *pdev,
struct drm_encoder *encoder,
const struct dw_hdmi_qp_plat_data *plat_data);
+void dw_hdmi_qp_suspend(struct device *dev, struct dw_hdmi_qp *hdmi);
void dw_hdmi_qp_resume(struct device *dev, struct dw_hdmi_qp *hdmi);
#endif /* __DW_HDMI_QP__ */
diff --git a/include/drm/bridge/inno_hdmi.h b/include/drm/bridge/inno_hdmi.h
new file mode 100644
index 000000000000..5bbcaeea94e2
--- /dev/null
+++ b/include/drm/bridge/inno_hdmi.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __INNO_HDMI__
+#define __INNO_HDMI__
+
+#include <linux/types.h>
+
+struct device;
+struct drm_encoder;
+struct drm_display_mode;
+struct inno_hdmi;
+
+struct inno_hdmi_plat_ops {
+ void (*enable)(struct device *pdev, struct drm_display_mode *mode);
+};
+
+struct inno_hdmi_phy_config {
+ unsigned long pixelclock;
+ u8 pre_emphasis;
+ u8 voltage_level_control;
+};
+
+struct inno_hdmi_plat_data {
+ const struct inno_hdmi_plat_ops *ops;
+ struct inno_hdmi_phy_config *phy_configs;
+ struct inno_hdmi_phy_config *default_phy_config;
+};
+
+struct inno_hdmi *inno_hdmi_bind(struct device *pdev,
+ struct drm_encoder *encoder,
+ const struct inno_hdmi_plat_data *plat_data);
+#endif /* __INNO_HDMI__ */
diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h
index 31d7ed589233..03005e474704 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -100,7 +100,6 @@ struct samsung_dsim_plat_data {
struct samsung_dsim {
struct mipi_dsi_host dsi_host;
struct drm_bridge bridge;
- struct drm_bridge *out_bridge;
struct device *dev;
struct drm_display_mode mode;
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index e4eebabab975..8b15d3eeb716 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -571,6 +571,8 @@
# define DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP (1 << 7)
#define DP_PANEL_REPLAY_CAP_X_GRANULARITY 0xb2
+# define DP_PANEL_REPLAY_FULL_LINE_GRANULARITY 0xffff
+
#define DP_PANEL_REPLAY_CAP_Y_GRANULARITY 0xb4
/* Link Configuration */
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index 85e868238e28..1d0acd58f486 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -555,6 +555,22 @@ ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset,
void *buffer, size_t size);
/**
+ * drm_dp_dpcd_readb() - read a single byte from the DPCD
+ * @aux: DisplayPort AUX channel
+ * @offset: address of the register to read
+ * @valuep: location where the value of the register will be stored
+ *
+ * Returns the number of bytes transferred (1) on success, or a negative
+ * error code on failure. In most of the cases you should be using
+ * drm_dp_dpcd_read_byte() instead.
+ */
+static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux,
+ unsigned int offset, u8 *valuep)
+{
+ return drm_dp_dpcd_read(aux, offset, valuep, 1);
+}
+
+/**
* drm_dp_dpcd_read_data() - read a series of bytes from the DPCD
* @aux: DisplayPort AUX channel (SST or MST)
* @offset: address of the (first) register to read
@@ -573,12 +589,29 @@ static inline int drm_dp_dpcd_read_data(struct drm_dp_aux *aux,
void *buffer, size_t size)
{
int ret;
+ size_t i;
+ u8 *buf = buffer;
ret = drm_dp_dpcd_read(aux, offset, buffer, size);
- if (ret < 0)
- return ret;
- if (ret < size)
- return -EPROTO;
+ if (ret >= 0) {
+ if (ret < size)
+ return -EPROTO;
+ return 0;
+ }
+
+ /*
+ * Workaround for USB-C hubs/adapters with buggy firmware that fail
+ * multi-byte AUX reads but work with single-byte reads.
+ * Known affected devices:
+ * - Lenovo USB-C to VGA adapter (VIA VL817, idVendor=17ef, idProduct=7217)
+ * - Dell DA310 USB-C hub (idVendor=413c, idProduct=c010)
+ * Attempt byte-by-byte reading as a fallback.
+ */
+ for (i = 0; i < size; i++) {
+ ret = drm_dp_dpcd_readb(aux, offset + i, &buf[i]);
+ if (ret < 0)
+ return ret;
+ }
return 0;
}
@@ -613,22 +646,6 @@ static inline int drm_dp_dpcd_write_data(struct drm_dp_aux *aux,
}
/**
- * drm_dp_dpcd_readb() - read a single byte from the DPCD
- * @aux: DisplayPort AUX channel
- * @offset: address of the register to read
- * @valuep: location where the value of the register will be stored
- *
- * Returns the number of bytes transferred (1) on success, or a negative
- * error code on failure. In most of the cases you should be using
- * drm_dp_dpcd_read_byte() instead.
- */
-static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux,
- unsigned int offset, u8 *valuep)
-{
- return drm_dp_dpcd_read(aux, offset, valuep, 1);
-}
-
-/**
* drm_dp_dpcd_writeb() - write a single byte to the DPCD
* @aux: DisplayPort AUX channel
* @offset: address of the register to write
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 74ce26fa8838..0b1b32bcd2bd 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -30,7 +30,6 @@
#include <drm/drm_crtc.h>
#include <drm/drm_util.h>
-#include <drm/drm_colorop.h>
/**
* struct drm_crtc_commit - track modeset commits on a CRTC
@@ -263,6 +262,19 @@ struct drm_private_state;
*/
struct drm_private_state_funcs {
/**
+ * @atomic_create_state:
+ *
+ * Allocates a pristine, initialized, state for the private
+ * object and returns it.
+ *
+ * RETURNS:
+ *
+ * A new, pristine, private state instance or an error pointer
+ * on failure.
+ */
+ struct drm_private_state *(*atomic_create_state)(struct drm_private_obj *obj);
+
+ /**
* @atomic_duplicate_state:
*
* Duplicate the current state of the private object and return it. It
@@ -712,14 +724,22 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
struct drm_colorop_state *
drm_atomic_get_colorop_state(struct drm_atomic_state *state,
struct drm_colorop *colorop);
+
+struct drm_colorop_state *
+drm_atomic_get_old_colorop_state(struct drm_atomic_state *state,
+ struct drm_colorop *colorop);
+struct drm_colorop_state *
+drm_atomic_get_new_colorop_state(struct drm_atomic_state *state,
+ struct drm_colorop *colorop);
+
struct drm_connector_state * __must_check
drm_atomic_get_connector_state(struct drm_atomic_state *state,
struct drm_connector *connector);
-void drm_atomic_private_obj_init(struct drm_device *dev,
- struct drm_private_obj *obj,
- struct drm_private_state *state,
- const struct drm_private_state_funcs *funcs);
+int drm_atomic_private_obj_init(struct drm_device *dev,
+ struct drm_private_obj *obj,
+ struct drm_private_state *state,
+ const struct drm_private_state_funcs *funcs);
void drm_atomic_private_obj_fini(struct drm_private_obj *obj);
struct drm_private_state * __must_check
@@ -809,36 +829,6 @@ drm_atomic_get_new_plane_state(const struct drm_atomic_state *state,
}
/**
- * drm_atomic_get_old_colorop_state - get colorop state, if it exists
- * @state: global atomic state object
- * @colorop: colorop to grab
- *
- * This function returns the old colorop state for the given colorop, or
- * NULL if the colorop is not part of the global atomic state.
- */
-static inline struct drm_colorop_state *
-drm_atomic_get_old_colorop_state(struct drm_atomic_state *state,
- struct drm_colorop *colorop)
-{
- return state->colorops[drm_colorop_index(colorop)].old_state;
-}
-
-/**
- * drm_atomic_get_new_colorop_state - get colorop state, if it exists
- * @state: global atomic state object
- * @colorop: colorop to grab
- *
- * This function returns the new colorop state for the given colorop, or
- * NULL if the colorop is not part of the global atomic state.
- */
-static inline struct drm_colorop_state *
-drm_atomic_get_new_colorop_state(struct drm_atomic_state *state,
- struct drm_colorop *colorop)
-{
- return state->colorops[drm_colorop_index(colorop)].new_state;
-}
-
-/**
* drm_atomic_get_old_connector_state - get connector state, if it exists
* @state: global atomic state object
* @connector: connector to grab
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 53382fe93537..e154ee4f0696 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -60,6 +60,12 @@ int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
int drm_atomic_helper_check_planes(struct drm_device *dev,
struct drm_atomic_state *state);
int drm_atomic_helper_check_crtc_primary_plane(struct drm_crtc_state *crtc_state);
+void drm_atomic_helper_commit_encoder_bridge_disable(struct drm_device *dev,
+ struct drm_atomic_state *state);
+void drm_atomic_helper_commit_crtc_disable(struct drm_device *dev,
+ struct drm_atomic_state *state);
+void drm_atomic_helper_commit_encoder_bridge_post_disable(struct drm_device *dev,
+ struct drm_atomic_state *state);
int drm_atomic_helper_check(struct drm_device *dev,
struct drm_atomic_state *state);
void drm_atomic_helper_commit_tail(struct drm_atomic_state *state);
@@ -89,8 +95,24 @@ drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
void
drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state);
+void drm_atomic_helper_commit_crtc_set_mode(struct drm_device *dev,
+ struct drm_atomic_state *state);
+
void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
struct drm_atomic_state *state);
+
+void drm_atomic_helper_commit_writebacks(struct drm_device *dev,
+ struct drm_atomic_state *state);
+
+void drm_atomic_helper_commit_encoder_bridge_pre_enable(struct drm_device *dev,
+ struct drm_atomic_state *state);
+
+void drm_atomic_helper_commit_crtc_enable(struct drm_device *dev,
+ struct drm_atomic_state *state);
+
+void drm_atomic_helper_commit_encoder_bridge_enable(struct drm_device *dev,
+ struct drm_atomic_state *state);
+
void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
struct drm_atomic_state *old_state);
diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h
index b9740edb2658..900672c6ea90 100644
--- a/include/drm/drm_atomic_state_helper.h
+++ b/include/drm/drm_atomic_state_helper.h
@@ -84,6 +84,9 @@ void
__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state);
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
struct drm_connector_state *state);
+
+void __drm_atomic_helper_private_obj_create_state(struct drm_private_obj *obj,
+ struct drm_private_state *state);
void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
struct drm_private_state *state);
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index d2683846cc61..4f19f7064ee3 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -176,33 +176,17 @@ struct drm_bridge_funcs {
/**
* @disable:
*
- * The @disable callback should disable the bridge.
+ * This callback should disable the bridge. It is called right before
+ * the preceding element in the display pipe is disabled. If the
+ * preceding element is a bridge this means it's called before that
+ * bridge's @disable vfunc. If the preceding element is a &drm_encoder
+ * it's called right before the &drm_encoder_helper_funcs.disable,
+ * &drm_encoder_helper_funcs.prepare or &drm_encoder_helper_funcs.dpms
+ * hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is still running when this callback is called.
*
- *
- * If the preceding element is a &drm_bridge, then this is called before
- * that bridge is disabled via one of:
- *
- * - &drm_bridge_funcs.disable
- * - &drm_bridge_funcs.atomic_disable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called before the encoder is disabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_disable
- * - &drm_encoder_helper_funcs.prepare
- * - &drm_encoder_helper_funcs.disable
- * - &drm_encoder_helper_funcs.dpms
- *
- * and the CRTC is disabled via one of:
- *
- * - &drm_crtc_helper_funcs.prepare
- * - &drm_crtc_helper_funcs.atomic_disable
- * - &drm_crtc_helper_funcs.disable
- * - &drm_crtc_helper_funcs.dpms.
- *
* The @disable callback is optional.
*
* NOTE:
@@ -215,34 +199,17 @@ struct drm_bridge_funcs {
/**
* @post_disable:
*
- * The bridge must assume that the display pipe (i.e. clocks and timing
- * signals) feeding this bridge is no longer running when the
- * @post_disable is called.
- *
- * This callback should perform all the actions required by the hardware
- * after it has stopped receiving signals from the preceding element.
- *
- * If the preceding element is a &drm_bridge, then this is called after
- * that bridge is post-disabled (unless marked otherwise by the
- * @pre_enable_prev_first flag) via one of:
- *
- * - &drm_bridge_funcs.post_disable
- * - &drm_bridge_funcs.atomic_post_disable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called after the encoder is disabled via one of:
+ * This callback should disable the bridge. It is called right after the
+ * preceding element in the display pipe is disabled. If the preceding
+ * element is a bridge this means it's called after that bridge's
+ * @post_disable function. If the preceding element is a &drm_encoder
+ * it's called right after the encoder's
+ * &drm_encoder_helper_funcs.disable, &drm_encoder_helper_funcs.prepare
+ * or &drm_encoder_helper_funcs.dpms hook.
*
- * - &drm_encoder_helper_funcs.atomic_disable
- * - &drm_encoder_helper_funcs.prepare
- * - &drm_encoder_helper_funcs.disable
- * - &drm_encoder_helper_funcs.dpms
- *
- * and the CRTC is disabled via one of:
- *
- * - &drm_crtc_helper_funcs.prepare
- * - &drm_crtc_helper_funcs.atomic_disable
- * - &drm_crtc_helper_funcs.disable
- * - &drm_crtc_helper_funcs.dpms
+ * The bridge must assume that the display pipe (i.e. clocks and timing
+ * signals) feeding it is no longer running when this callback is
+ * called.
*
* The @post_disable callback is optional.
*
@@ -285,30 +252,18 @@ struct drm_bridge_funcs {
/**
* @pre_enable:
*
- * The display pipe (i.e. clocks and timing signals) feeding this bridge
- * will not yet be running when the @pre_enable is called.
- *
- * This callback should perform all the necessary actions to prepare the
- * bridge to accept signals from the preceding element.
- *
- * If the preceding element is a &drm_bridge, then this is called before
- * that bridge is pre-enabled (unless marked otherwise by
- * @pre_enable_prev_first flag) via one of:
- *
- * - &drm_bridge_funcs.pre_enable
- * - &drm_bridge_funcs.atomic_pre_enable
+ * This callback should enable the bridge. It is called right before
+ * the preceding element in the display pipe is enabled. If the
+ * preceding element is a bridge this means it's called before that
+ * bridge's @pre_enable function. If the preceding element is a
+ * &drm_encoder it's called right before the encoder's
+ * &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or
+ * &drm_encoder_helper_funcs.dpms hook.
*
- * If the preceding element of the bridge is a display controller, then
- * this callback is called before the CRTC is enabled via one of:
- *
- * - &drm_crtc_helper_funcs.atomic_enable
- * - &drm_crtc_helper_funcs.commit
- *
- * and the encoder is enabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_enable
- * - &drm_encoder_helper_funcs.enable
- * - &drm_encoder_helper_funcs.commit
+ * The display pipe (i.e. clocks and timing signals) feeding this bridge
+ * will not yet be running when this callback is called. The bridge must
+ * not enable the display link feeding the next bridge in the chain (if
+ * there is one) when this callback is called.
*
* The @pre_enable callback is optional.
*
@@ -322,31 +277,19 @@ struct drm_bridge_funcs {
/**
* @enable:
*
- * The @enable callback should enable the bridge.
+ * This callback should enable the bridge. It is called right after
+ * the preceding element in the display pipe is enabled. If the
+ * preceding element is a bridge this means it's called after that
+ * bridge's @enable function. If the preceding element is a
+ * &drm_encoder it's called right after the encoder's
+ * &drm_encoder_helper_funcs.enable, &drm_encoder_helper_funcs.commit or
+ * &drm_encoder_helper_funcs.dpms hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is running when this callback is called. This
* callback must enable the display link feeding the next bridge in the
* chain if there is one.
*
- * If the preceding element is a &drm_bridge, then this is called after
- * that bridge is enabled via one of:
- *
- * - &drm_bridge_funcs.enable
- * - &drm_bridge_funcs.atomic_enable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called after the CRTC is enabled via one of:
- *
- * - &drm_crtc_helper_funcs.atomic_enable
- * - &drm_crtc_helper_funcs.commit
- *
- * and the encoder is enabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_enable
- * - &drm_encoder_helper_funcs.enable
- * - drm_encoder_helper_funcs.commit
- *
* The @enable callback is optional.
*
* NOTE:
@@ -359,30 +302,17 @@ struct drm_bridge_funcs {
/**
* @atomic_pre_enable:
*
- * The display pipe (i.e. clocks and timing signals) feeding this bridge
- * will not yet be running when the @atomic_pre_enable is called.
- *
- * This callback should perform all the necessary actions to prepare the
- * bridge to accept signals from the preceding element.
+ * This callback should enable the bridge. It is called right before
+ * the preceding element in the display pipe is enabled. If the
+ * preceding element is a bridge this means it's called before that
+ * bridge's @atomic_pre_enable or @pre_enable function. If the preceding
+ * element is a &drm_encoder it's called right before the encoder's
+ * &drm_encoder_helper_funcs.atomic_enable hook.
*
- * If the preceding element is a &drm_bridge, then this is called before
- * that bridge is pre-enabled (unless marked otherwise by
- * @pre_enable_prev_first flag) via one of:
- *
- * - &drm_bridge_funcs.pre_enable
- * - &drm_bridge_funcs.atomic_pre_enable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called before the CRTC is enabled via one of:
- *
- * - &drm_crtc_helper_funcs.atomic_enable
- * - &drm_crtc_helper_funcs.commit
- *
- * and the encoder is enabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_enable
- * - &drm_encoder_helper_funcs.enable
- * - &drm_encoder_helper_funcs.commit
+ * The display pipe (i.e. clocks and timing signals) feeding this bridge
+ * will not yet be running when this callback is called. The bridge must
+ * not enable the display link feeding the next bridge in the chain (if
+ * there is one) when this callback is called.
*
* The @atomic_pre_enable callback is optional.
*/
@@ -392,31 +322,18 @@ struct drm_bridge_funcs {
/**
* @atomic_enable:
*
- * The @atomic_enable callback should enable the bridge.
+ * This callback should enable the bridge. It is called right after
+ * the preceding element in the display pipe is enabled. If the
+ * preceding element is a bridge this means it's called after that
+ * bridge's @atomic_enable or @enable function. If the preceding element
+ * is a &drm_encoder it's called right after the encoder's
+ * &drm_encoder_helper_funcs.atomic_enable hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is running when this callback is called. This
* callback must enable the display link feeding the next bridge in the
* chain if there is one.
*
- * If the preceding element is a &drm_bridge, then this is called after
- * that bridge is enabled via one of:
- *
- * - &drm_bridge_funcs.enable
- * - &drm_bridge_funcs.atomic_enable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called after the CRTC is enabled via one of:
- *
- * - &drm_crtc_helper_funcs.atomic_enable
- * - &drm_crtc_helper_funcs.commit
- *
- * and the encoder is enabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_enable
- * - &drm_encoder_helper_funcs.enable
- * - drm_encoder_helper_funcs.commit
- *
* The @atomic_enable callback is optional.
*/
void (*atomic_enable)(struct drm_bridge *bridge,
@@ -424,32 +341,16 @@ struct drm_bridge_funcs {
/**
* @atomic_disable:
*
- * The @atomic_disable callback should disable the bridge.
+ * This callback should disable the bridge. It is called right before
+ * the preceding element in the display pipe is disabled. If the
+ * preceding element is a bridge this means it's called before that
+ * bridge's @atomic_disable or @disable vfunc. If the preceding element
+ * is a &drm_encoder it's called right before the
+ * &drm_encoder_helper_funcs.atomic_disable hook.
*
* The bridge can assume that the display pipe (i.e. clocks and timing
* signals) feeding it is still running when this callback is called.
*
- * If the preceding element is a &drm_bridge, then this is called before
- * that bridge is disabled via one of:
- *
- * - &drm_bridge_funcs.disable
- * - &drm_bridge_funcs.atomic_disable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called before the encoder is disabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_disable
- * - &drm_encoder_helper_funcs.prepare
- * - &drm_encoder_helper_funcs.disable
- * - &drm_encoder_helper_funcs.dpms
- *
- * and the CRTC is disabled via one of:
- *
- * - &drm_crtc_helper_funcs.prepare
- * - &drm_crtc_helper_funcs.atomic_disable
- * - &drm_crtc_helper_funcs.disable
- * - &drm_crtc_helper_funcs.dpms.
- *
* The @atomic_disable callback is optional.
*/
void (*atomic_disable)(struct drm_bridge *bridge,
@@ -458,34 +359,16 @@ struct drm_bridge_funcs {
/**
* @atomic_post_disable:
*
- * The bridge must assume that the display pipe (i.e. clocks and timing
- * signals) feeding this bridge is no longer running when the
- * @atomic_post_disable is called.
- *
- * This callback should perform all the actions required by the hardware
- * after it has stopped receiving signals from the preceding element.
- *
- * If the preceding element is a &drm_bridge, then this is called after
- * that bridge is post-disabled (unless marked otherwise by the
- * @pre_enable_prev_first flag) via one of:
- *
- * - &drm_bridge_funcs.post_disable
- * - &drm_bridge_funcs.atomic_post_disable
- *
- * If the preceding element of the bridge is a display controller, then
- * this callback is called after the encoder is disabled via one of:
- *
- * - &drm_encoder_helper_funcs.atomic_disable
- * - &drm_encoder_helper_funcs.prepare
- * - &drm_encoder_helper_funcs.disable
- * - &drm_encoder_helper_funcs.dpms
+ * This callback should disable the bridge. It is called right after the
+ * preceding element in the display pipe is disabled. If the preceding
+ * element is a bridge this means it's called after that bridge's
+ * @atomic_post_disable or @post_disable function. If the preceding
+ * element is a &drm_encoder it's called right after the encoder's
+ * &drm_encoder_helper_funcs.atomic_disable hook.
*
- * and the CRTC is disabled via one of:
- *
- * - &drm_crtc_helper_funcs.prepare
- * - &drm_crtc_helper_funcs.atomic_disable
- * - &drm_crtc_helper_funcs.disable
- * - &drm_crtc_helper_funcs.dpms
+ * The bridge must assume that the display pipe (i.e. clocks and timing
+ * signals) feeding it is no longer running when this callback is
+ * called.
*
* The @atomic_post_disable callback is optional.
*/
@@ -731,6 +614,7 @@ struct drm_bridge_funcs {
* controllers for HDMI bridges.
*/
void (*hpd_notify)(struct drm_bridge *bridge,
+ struct drm_connector *connector,
enum drm_connector_status status);
/**
@@ -784,29 +668,113 @@ struct drm_bridge_funcs {
unsigned long long tmds_rate);
/**
- * @hdmi_clear_infoframe:
+ * @hdmi_clear_avi_infoframe:
+ *
+ * This callback clears the infoframes in the hardware during commit.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops.
+ */
+ int (*hdmi_clear_avi_infoframe)(struct drm_bridge *bridge);
+
+ /**
+ * @hdmi_write_avi_infoframe:
+ *
+ * Program the infoframe into the hardware.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops.
+ */
+ int (*hdmi_write_avi_infoframe)(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len);
+
+ /**
+ * @hdmi_clear_hdmi_infoframe:
*
* This callback clears the infoframes in the hardware during commit.
- * It will be called multiple times, once for every disabled infoframe
- * type.
*
* This callback is optional but it must be implemented by bridges that
* set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops.
*/
- int (*hdmi_clear_infoframe)(struct drm_bridge *bridge,
- enum hdmi_infoframe_type type);
+ int (*hdmi_clear_hdmi_infoframe)(struct drm_bridge *bridge);
+
/**
- * @hdmi_write_infoframe:
+ * @hdmi_write_hdmi_infoframe:
*
- * Program the infoframe into the hardware. It will be called multiple
- * times, once for every updated infoframe type.
+ * Program the infoframe into the hardware.
*
* This callback is optional but it must be implemented by bridges that
* set the DRM_BRIDGE_OP_HDMI flag in their &drm_bridge->ops.
*/
- int (*hdmi_write_infoframe)(struct drm_bridge *bridge,
- enum hdmi_infoframe_type type,
- const u8 *buffer, size_t len);
+ int (*hdmi_write_hdmi_infoframe)(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len);
+
+ /**
+ * @hdmi_clear_hdr_drm_infoframe:
+ *
+ * This callback clears the infoframes in the hardware during commit.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their
+ * &drm_bridge->ops.
+ */
+ int (*hdmi_clear_hdr_drm_infoframe)(struct drm_bridge *bridge);
+
+ /**
+ * @hdmi_write_hdr_drm_infoframe:
+ *
+ * Program the infoframe into the hardware.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME flag in their
+ * &drm_bridge->ops.
+ */
+ int (*hdmi_write_hdr_drm_infoframe)(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len);
+
+ /**
+ * @hdmi_clear_spd_infoframe:
+ *
+ * This callback clears the infoframes in the hardware during commit.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their
+ * &drm_bridge->ops.
+ */
+ int (*hdmi_clear_spd_infoframe)(struct drm_bridge *bridge);
+
+ /**
+ * @hdmi_write_spd_infoframe:
+ *
+ * Program the infoframe into the hardware.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME flag in their
+ * &drm_bridge->ops.
+ */
+ int (*hdmi_write_spd_infoframe)(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len);
+
+ /**
+ * @hdmi_clear_audio_infoframe:
+ *
+ * This callback clears the infoframes in the hardware during commit.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops.
+ */
+ int (*hdmi_clear_audio_infoframe)(struct drm_bridge *bridge);
+
+ /**
+ * @hdmi_write_audio_infoframe:
+ *
+ * Program the infoframe into the hardware.
+ *
+ * This callback is optional but it must be implemented by bridges that
+ * set the DRM_BRIDGE_OP_HDMI_AUDIO flag in their &drm_bridge->ops.
+ */
+ int (*hdmi_write_audio_infoframe)(struct drm_bridge *bridge,
+ const u8 *buffer, size_t len);
/**
* @hdmi_audio_startup:
@@ -1062,7 +1030,11 @@ enum drm_bridge_ops {
/**
* @DRM_BRIDGE_OP_HDMI: The bridge provides HDMI connector operations,
* including infoframes support. Bridges that set this flag must
- * implement the &drm_bridge_funcs->write_infoframe callback.
+ * provide HDMI-related information and implement the
+ * &drm_bridge_funcs->clear_avi_infoframe,
+ * &drm_bridge_funcs->write_avi_infoframe,
+ * &drm_bridge_funcs->clear_hdmi_infoframe and
+ * &drm_bridge_funcs->write_hdmi_infoframe callbacks.
*
* Note: currently there can be at most one bridge in a chain that sets
* this bit. This is to simplify corresponding glue code in connector
@@ -1074,6 +1046,9 @@ enum drm_bridge_ops {
* Bridges that set this flag must implement the
* &drm_bridge_funcs->hdmi_audio_prepare and
* &drm_bridge_funcs->hdmi_audio_shutdown callbacks.
+ * If the bridge implements @DRM_BRIDGE_OP_HDMI, it also must implement
+ * &drm_bridge_funcs->hdmi_write_audio_infoframe and
+ * &drm_bridge_funcs->hdmi_cleaer_audio_infoframe callbacks.
*
* Note: currently there can be at most one bridge in a chain that sets
* this bit. This is to simplify corresponding glue code in connector
@@ -1105,6 +1080,18 @@ enum drm_bridge_ops {
* to be present.
*/
DRM_BRIDGE_OP_HDMI_CEC_ADAPTER = BIT(8),
+ /**
+ * @DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME: The bridge supports
+ * &drm_bridge_funcs->hdmi_write_hdr_drm_infoframe and
+ * &drm_bridge_funcs->hdmi_clear_hdr_drm_infoframe callbacks.
+ */
+ DRM_BRIDGE_OP_HDMI_HDR_DRM_INFOFRAME = BIT(9),
+ /**
+ * @DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME: The bridge supports
+ * &drm_bridge_funcs->hdmi_write_spd_infoframe and
+ * &drm_bridge_funcs->hdmi_clear_spd_infoframe callbacks.
+ */
+ DRM_BRIDGE_OP_HDMI_SPD_INFOFRAME = BIT(10),
};
/**
@@ -1278,6 +1265,17 @@ struct drm_bridge {
* @hpd_cb.
*/
void *hpd_data;
+
+ /**
+ * @next_bridge: Pointer to the following bridge, automatically put
+ * when this bridge is freed (i.e. at destroy time). This is for
+ * drivers needing to store a pointer to the next bridge in the
+ * chain, and ensures any code still holding a reference to this
+ * bridge after its removal cannot use-after-free the next
+ * bridge. Any other bridge pointers stored by the driver must be
+ * put in the .destroy callback by driver code.
+ */
+ struct drm_bridge *next_bridge;
};
static inline struct drm_bridge *
@@ -1325,8 +1323,13 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
enum drm_bridge_attach_flags flags);
#ifdef CONFIG_OF
+struct drm_bridge *of_drm_find_and_get_bridge(struct device_node *np);
struct drm_bridge *of_drm_find_bridge(struct device_node *np);
#else
+static inline struct drm_bridge *of_drm_find_and_get_bridge(struct device_node *np)
+{
+ return NULL;
+}
static inline struct drm_bridge *of_drm_find_bridge(struct device_node *np)
{
return NULL;
diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h
index b909fa8f810a..3054369bebff 100644
--- a/include/drm/drm_buddy.h
+++ b/include/drm/drm_buddy.h
@@ -6,166 +6,13 @@
#ifndef __DRM_BUDDY_H__
#define __DRM_BUDDY_H__
-#include <linux/bitops.h>
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <linux/rbtree.h>
+#include <linux/gpu_buddy.h>
struct drm_printer;
-#define DRM_BUDDY_RANGE_ALLOCATION BIT(0)
-#define DRM_BUDDY_TOPDOWN_ALLOCATION BIT(1)
-#define DRM_BUDDY_CONTIGUOUS_ALLOCATION BIT(2)
-#define DRM_BUDDY_CLEAR_ALLOCATION BIT(3)
-#define DRM_BUDDY_CLEARED BIT(4)
-#define DRM_BUDDY_TRIM_DISABLE BIT(5)
-
-struct drm_buddy_block {
-#define DRM_BUDDY_HEADER_OFFSET GENMASK_ULL(63, 12)
-#define DRM_BUDDY_HEADER_STATE GENMASK_ULL(11, 10)
-#define DRM_BUDDY_ALLOCATED (1 << 10)
-#define DRM_BUDDY_FREE (2 << 10)
-#define DRM_BUDDY_SPLIT (3 << 10)
-#define DRM_BUDDY_HEADER_CLEAR GENMASK_ULL(9, 9)
-/* Free to be used, if needed in the future */
-#define DRM_BUDDY_HEADER_UNUSED GENMASK_ULL(8, 6)
-#define DRM_BUDDY_HEADER_ORDER GENMASK_ULL(5, 0)
- u64 header;
-
- struct drm_buddy_block *left;
- struct drm_buddy_block *right;
- struct drm_buddy_block *parent;
-
- void *private; /* owned by creator */
-
- /*
- * While the block is allocated by the user through drm_buddy_alloc*,
- * the user has ownership of the link, for example to maintain within
- * a list, if so desired. As soon as the block is freed with
- * drm_buddy_free* ownership is given back to the mm.
- */
- union {
- struct rb_node rb;
- struct list_head link;
- };
-
- struct list_head tmp_link;
-};
-
-/* Order-zero must be at least SZ_4K */
-#define DRM_BUDDY_MAX_ORDER (63 - 12)
-
-/*
- * Binary Buddy System.
- *
- * Locking should be handled by the user, a simple mutex around
- * drm_buddy_alloc* and drm_buddy_free* should suffice.
- */
-struct drm_buddy {
- /* Maintain a free list for each order. */
- struct rb_root **free_trees;
-
- /*
- * Maintain explicit binary tree(s) to track the allocation of the
- * address space. This gives us a simple way of finding a buddy block
- * and performing the potentially recursive merge step when freeing a
- * block. Nodes are either allocated or free, in which case they will
- * also exist on the respective free list.
- */
- struct drm_buddy_block **roots;
-
- /*
- * Anything from here is public, and remains static for the lifetime of
- * the mm. Everything above is considered do-not-touch.
- */
- unsigned int n_roots;
- unsigned int max_order;
-
- /* Must be at least SZ_4K */
- u64 chunk_size;
- u64 size;
- u64 avail;
- u64 clear_avail;
-};
-
-static inline u64
-drm_buddy_block_offset(const struct drm_buddy_block *block)
-{
- return block->header & DRM_BUDDY_HEADER_OFFSET;
-}
-
-static inline unsigned int
-drm_buddy_block_order(struct drm_buddy_block *block)
-{
- return block->header & DRM_BUDDY_HEADER_ORDER;
-}
-
-static inline unsigned int
-drm_buddy_block_state(struct drm_buddy_block *block)
-{
- return block->header & DRM_BUDDY_HEADER_STATE;
-}
-
-static inline bool
-drm_buddy_block_is_allocated(struct drm_buddy_block *block)
-{
- return drm_buddy_block_state(block) == DRM_BUDDY_ALLOCATED;
-}
-
-static inline bool
-drm_buddy_block_is_clear(struct drm_buddy_block *block)
-{
- return block->header & DRM_BUDDY_HEADER_CLEAR;
-}
-
-static inline bool
-drm_buddy_block_is_free(struct drm_buddy_block *block)
-{
- return drm_buddy_block_state(block) == DRM_BUDDY_FREE;
-}
-
-static inline bool
-drm_buddy_block_is_split(struct drm_buddy_block *block)
-{
- return drm_buddy_block_state(block) == DRM_BUDDY_SPLIT;
-}
-
-static inline u64
-drm_buddy_block_size(struct drm_buddy *mm,
- struct drm_buddy_block *block)
-{
- return mm->chunk_size << drm_buddy_block_order(block);
-}
-
-int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size);
-
-void drm_buddy_fini(struct drm_buddy *mm);
-
-struct drm_buddy_block *
-drm_get_buddy(struct drm_buddy_block *block);
-
-int drm_buddy_alloc_blocks(struct drm_buddy *mm,
- u64 start, u64 end, u64 size,
- u64 min_page_size,
- struct list_head *blocks,
- unsigned long flags);
-
-int drm_buddy_block_trim(struct drm_buddy *mm,
- u64 *start,
- u64 new_size,
- struct list_head *blocks);
-
-void drm_buddy_reset_clear(struct drm_buddy *mm, bool is_clear);
-
-void drm_buddy_free_block(struct drm_buddy *mm, struct drm_buddy_block *block);
-
-void drm_buddy_free_list(struct drm_buddy *mm,
- struct list_head *objects,
- unsigned int flags);
-
-void drm_buddy_print(struct drm_buddy *mm, struct drm_printer *p);
-void drm_buddy_block_print(struct drm_buddy *mm,
- struct drm_buddy_block *block,
+/* DRM-specific GPU Buddy Allocator print helpers */
+void drm_buddy_print(struct gpu_buddy *mm, struct drm_printer *p);
+void drm_buddy_block_print(struct gpu_buddy *mm,
+ struct gpu_buddy_block *block,
struct drm_printer *p);
#endif
diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
index c972a8a3385b..49a21f3dcb36 100644
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -196,6 +196,9 @@ struct drm_client_buffer {
};
struct drm_client_buffer *
+drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height,
+ u32 format, u32 handle, u32 pitch);
+struct drm_client_buffer *
drm_client_buffer_create_dumb(struct drm_client_dev *client, u32 width, u32 height, u32 format);
void drm_client_buffer_delete(struct drm_client_buffer *buffer);
int drm_client_buffer_flush(struct drm_client_buffer *buffer, struct drm_rect *rect);
diff --git a/include/drm/drm_colorop.h b/include/drm/drm_colorop.h
index a3a32f9f918c..bd082854ca74 100644
--- a/include/drm/drm_colorop.h
+++ b/include/drm/drm_colorop.h
@@ -188,6 +188,19 @@ struct drm_colorop_state {
};
/**
+ * struct drm_colorop_funcs - driver colorop control functions
+ */
+struct drm_colorop_funcs {
+ /**
+ * @destroy:
+ *
+ * Clean up colorop resources. This is called at driver unload time
+ * through drm_mode_config_cleanup()
+ */
+ void (*destroy)(struct drm_colorop *colorop);
+};
+
+/**
* struct drm_colorop - DRM color operation control structure
*
* A colorop represents one color operation. They can be chained via
@@ -362,6 +375,8 @@ struct drm_colorop {
*/
struct drm_property *next_property;
+ /** @funcs: colorop control functions */
+ const struct drm_colorop_funcs *funcs;
};
#define obj_to_colorop(x) container_of(x, struct drm_colorop, base)
@@ -390,17 +405,22 @@ void drm_colorop_pipeline_destroy(struct drm_device *dev);
void drm_colorop_cleanup(struct drm_colorop *colorop);
int drm_plane_colorop_curve_1d_init(struct drm_device *dev, struct drm_colorop *colorop,
- struct drm_plane *plane, u64 supported_tfs, uint32_t flags);
+ struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
+ u64 supported_tfs, uint32_t flags);
int drm_plane_colorop_curve_1d_lut_init(struct drm_device *dev, struct drm_colorop *colorop,
- struct drm_plane *plane, uint32_t lut_size,
+ struct drm_plane *plane,
+ const struct drm_colorop_funcs *funcs,
+ uint32_t lut_size,
enum drm_colorop_lut1d_interpolation_type interpolation,
uint32_t flags);
int drm_plane_colorop_ctm_3x4_init(struct drm_device *dev, struct drm_colorop *colorop,
- struct drm_plane *plane, uint32_t flags);
+ struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
+ uint32_t flags);
int drm_plane_colorop_mult_init(struct drm_device *dev, struct drm_colorop *colorop,
- struct drm_plane *plane, uint32_t flags);
+ struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
+ uint32_t flags);
int drm_plane_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop,
- struct drm_plane *plane,
+ struct drm_plane *plane, const struct drm_colorop_funcs *funcs,
uint32_t lut_size,
enum drm_colorop_lut3d_interpolation_type interpolation,
uint32_t flags);
@@ -420,6 +440,8 @@ void drm_colorop_atomic_destroy_state(struct drm_colorop *colorop,
*/
void drm_colorop_reset(struct drm_colorop *colorop);
+void drm_colorop_destroy(struct drm_colorop *colorop);
+
/**
* drm_colorop_index - find the index of a registered colorop
* @colorop: colorop to find index for
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8f34f4b8183d..c18be8c19de0 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1222,44 +1222,24 @@ struct drm_connector_cec_funcs {
};
/**
- * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ * struct drm_connector_infoframe_funcs - InfoFrame-related functions
*/
-struct drm_connector_hdmi_funcs {
- /**
- * @tmds_char_rate_valid:
- *
- * This callback is invoked at atomic_check time to figure out
- * whether a particular TMDS character rate is supported by the
- * driver.
- *
- * The @tmds_char_rate_valid callback is optional.
- *
- * Returns:
- *
- * Either &drm_mode_status.MODE_OK or one of the failure reasons
- * in &enum drm_mode_status.
- */
- enum drm_mode_status
- (*tmds_char_rate_valid)(const struct drm_connector *connector,
- const struct drm_display_mode *mode,
- unsigned long long tmds_rate);
-
+struct drm_connector_infoframe_funcs {
/**
* @clear_infoframe:
*
* This callback is invoked through
* @drm_atomic_helper_connector_hdmi_update_infoframes during a
* commit to clear the infoframes into the hardware. It will be
- * called multiple times, once for every disabled infoframe
- * type.
+ * called once for each frame type to be disabled.
*
- * The @clear_infoframe callback is optional.
+ * The @clear_infoframe callback is mandatory for AVI and HDMI-VS
+ * InfoFrame types.
*
* Returns:
* 0 on success, a negative error code otherwise
*/
- int (*clear_infoframe)(struct drm_connector *connector,
- enum hdmi_infoframe_type type);
+ int (*clear_infoframe)(struct drm_connector *connector);
/**
* @write_infoframe:
@@ -1267,18 +1247,42 @@ struct drm_connector_hdmi_funcs {
* This callback is invoked through
* @drm_atomic_helper_connector_hdmi_update_infoframes during a
* commit to program the infoframes into the hardware. It will
- * be called multiple times, once for every updated infoframe
- * type.
+ * be called for every updated infoframe type.
*
- * The @write_infoframe callback is mandatory.
+ * The @write_infoframe callback is mandatory for AVI and HDMI-VS
+ * InfoFrame types.
*
* Returns:
* 0 on success, a negative error code otherwise
*/
int (*write_infoframe)(struct drm_connector *connector,
- enum hdmi_infoframe_type type,
const u8 *buffer, size_t len);
+};
+
+/**
+ * struct drm_connector_hdmi_funcs - drm_hdmi_connector control functions
+ */
+struct drm_connector_hdmi_funcs {
+ /**
+ * @tmds_char_rate_valid:
+ *
+ * This callback is invoked at atomic_check time to figure out
+ * whether a particular TMDS character rate is supported by the
+ * driver.
+ *
+ * The @tmds_char_rate_valid callback is optional.
+ *
+ * Returns:
+ *
+ * Either &drm_mode_status.MODE_OK or one of the failure reasons
+ * in &enum drm_mode_status.
+ */
+ enum drm_mode_status
+ (*tmds_char_rate_valid)(const struct drm_connector *connector,
+ const struct drm_display_mode *mode,
+ unsigned long long tmds_rate);
+
/**
* @read_edid:
*
@@ -1293,6 +1297,47 @@ struct drm_connector_hdmi_funcs {
* Valid EDID on success, NULL in case of failure.
*/
const struct drm_edid *(*read_edid)(struct drm_connector *connector);
+
+ /**
+ * @avi:
+ *
+ * Set of callbacks for handling the AVI InfoFrame. These callbacks are
+ * mandatory.
+ */
+ struct drm_connector_infoframe_funcs avi;
+
+ /**
+ * @hdmi:
+ *
+ * Set of callbacks for handling the HDMI Vendor-Specific InfoFrame.
+ * These callbacks are mandatory.
+ */
+ struct drm_connector_infoframe_funcs hdmi;
+
+ /**
+ * @audio:
+ *
+ * Set of callbacks for handling the Audio InfoFrame. These callbacks
+ * are optional, but they are required for drivers which use
+ * drm_atomic_helper_connector_hdmi_update_audio_infoframe().
+ */
+ struct drm_connector_infoframe_funcs audio;
+
+ /**
+ * @hdr_drm:
+ *
+ * Set of callbacks for handling the HDR DRM InfoFrame. These callbacks
+ * are mandatory if HDR output is to be supported.
+ */
+ struct drm_connector_infoframe_funcs hdr_drm;
+
+ /**
+ * @spd:
+ *
+ * Set of callbacks for handling the SPD InfoFrame. These callbacks are
+ * optional.
+ */
+ struct drm_connector_infoframe_funcs spd;
};
/**
@@ -2448,6 +2493,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
u32 scaling_mode_mask);
int drm_connector_attach_vrr_capable_property(
struct drm_connector *connector);
+void drm_connector_attach_panel_type_property(struct drm_connector *connector);
int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector);
int drm_connector_attach_colorspace_property(struct drm_connector *connector);
int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector);
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 05cca77b7249..15274b8a1d97 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -271,111 +271,6 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
-#else
-static inline void drm_fb_helper_prepare(struct drm_device *dev,
- struct drm_fb_helper *helper,
- unsigned int preferred_bpp,
- const struct drm_fb_helper_funcs *funcs)
-{
-}
-
-static inline void drm_fb_helper_unprepare(struct drm_fb_helper *fb_helper)
-{
-}
-
-static inline int drm_fb_helper_init(struct drm_device *dev,
- struct drm_fb_helper *helper)
-{
- /* So drivers can use it to free the struct */
- helper->dev = dev;
- dev->fb_helper = helper;
-
- return 0;
-}
-
-static inline void drm_fb_helper_fini(struct drm_fb_helper *helper)
-{
- if (helper && helper->dev)
- helper->dev->fb_helper = NULL;
-}
-
-static inline int drm_fb_helper_blank(int blank, struct fb_info *info)
-{
- return 0;
-}
-
-static inline int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- return 0;
-}
-
-static inline int drm_fb_helper_set_par(struct fb_info *info)
-{
- return 0;
-}
-
-static inline int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- return 0;
-}
-
-static inline int
-drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
-{
- return 0;
-}
-
-static inline void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper)
-{
-}
-
-static inline void
-drm_fb_helper_fill_info(struct fb_info *info,
- struct drm_fb_helper *fb_helper,
- struct drm_fb_helper_surface_size *sizes)
-{
-}
-
-static inline int drm_fb_helper_setcmap(struct fb_cmap *cmap,
- struct fb_info *info)
-{
- return 0;
-}
-
-static inline int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
-{
- return 0;
-}
-
-#ifdef CONFIG_FB_DEFERRED_IO
-static inline void drm_fb_helper_deferred_io(struct fb_info *info,
- struct list_head *pagelist)
-{
-}
-#endif
-
-static inline void drm_fb_helper_set_suspend(struct drm_fb_helper *fb_helper,
- bool suspend)
-{
-}
-
-static inline void
-drm_fb_helper_set_suspend_unlocked(struct drm_fb_helper *fb_helper, bool suspend)
-{
-}
-
-static inline int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
-{
- return 0;
-}
-
-static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
-{
- return 0;
-}
#endif
#endif
diff --git a/include/drm/drm_gem_shmem_helper.h b/include/drm/drm_gem_shmem_helper.h
index 6b6478f5ca24..5ccdae21b94a 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -300,4 +300,15 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
.gem_prime_import = drm_gem_shmem_prime_import_no_map, \
.dumb_create = drm_gem_shmem_dumb_create
+/*
+ * Kunit helpers
+ */
+
+#if IS_ENABLED(CONFIG_KUNIT)
+int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map);
+void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map);
+int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv);
+int drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem);
+#endif
+
#endif /* __DRM_GEM_SHMEM_HELPER_H__ */
diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h
index fdfc575b2603..655bd9104ffb 100644
--- a/include/drm/drm_gpuvm.h
+++ b/include/drm/drm_gpuvm.h
@@ -736,8 +736,8 @@ drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
struct drm_gem_object *obj);
struct drm_gpuvm_bo *
-drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm,
- struct drm_gem_object *obj);
+drm_gpuvm_bo_obtain_locked(struct drm_gpuvm *gpuvm,
+ struct drm_gem_object *obj);
struct drm_gpuvm_bo *
drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *vm_bo);
@@ -1121,7 +1121,7 @@ void drm_gpuva_ops_free(struct drm_gpuvm *gpuvm,
struct drm_gpuva_ops *ops);
static inline void drm_gpuva_init_from_op(struct drm_gpuva *va,
- struct drm_gpuva_op_map *op)
+ const struct drm_gpuva_op_map *op)
{
va->va.addr = op->va.addr;
va->va.range = op->va.range;
@@ -1265,13 +1265,13 @@ int drm_gpuvm_sm_unmap_exec_lock(struct drm_gpuvm *gpuvm, struct drm_exec *exec,
void drm_gpuva_map(struct drm_gpuvm *gpuvm,
struct drm_gpuva *va,
- struct drm_gpuva_op_map *op);
+ const struct drm_gpuva_op_map *op);
void drm_gpuva_remap(struct drm_gpuva *prev,
struct drm_gpuva *next,
- struct drm_gpuva_op_remap *op);
+ const struct drm_gpuva_op_remap *op);
-void drm_gpuva_unmap(struct drm_gpuva_op_unmap *op);
+void drm_gpuva_unmap(const struct drm_gpuva_op_unmap *op);
/**
* drm_gpuva_op_remap_to_unmap_range() - Helper to get the start and range of
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 895fb820dba0..5e1dd0cfccde 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -601,6 +601,10 @@ struct drm_mode_config {
*/
struct drm_property *tile_property;
/**
+ * @panel_type_property: Default connector property for panel type
+ */
+ struct drm_property *panel_type_property;
+ /**
* @link_status_property: Default connector property for link status
* of a connector
*/
diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h
index c68edbd126d0..44a0d6f8d01f 100644
--- a/include/drm/drm_mode_object.h
+++ b/include/drm/drm_mode_object.h
@@ -133,6 +133,9 @@ int drm_object_property_get_value(struct drm_mode_object *obj,
int drm_object_property_get_default_value(struct drm_mode_object *obj,
struct drm_property *property,
uint64_t *val);
+int drm_object_immutable_property_get_value(struct drm_mode_object *obj,
+ struct drm_property *property,
+ uint64_t *val);
void drm_object_attach_property(struct drm_mode_object *obj,
struct drm_property *property,
diff --git a/include/drm/drm_of.h b/include/drm/drm_of.h
index 7f0256dae3f1..f2f2bf82eff9 100644
--- a/include/drm/drm_of.h
+++ b/include/drm/drm_of.h
@@ -5,6 +5,7 @@
#include <linux/err.h>
#include <linux/of_graph.h>
#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_DRM_PANEL_BRIDGE)
+#include <linux/of.h>
#include <drm/drm_bridge.h>
#endif
@@ -170,9 +171,12 @@ static inline int drm_of_panel_bridge_remove(const struct device_node *np,
if (!remote)
return -ENODEV;
- bridge = of_drm_find_bridge(remote);
+ bridge = of_drm_find_and_get_bridge(remote);
drm_panel_bridge_remove(bridge);
+ drm_bridge_put(bridge);
+ of_node_put(remote);
+
return 0;
#else
return -EINVAL;
diff --git a/include/drm/drm_property.h b/include/drm/drm_property.h
index 082f29156b3e..aa49b5a42bb5 100644
--- a/include/drm/drm_property.h
+++ b/include/drm/drm_property.h
@@ -284,6 +284,7 @@ int drm_property_replace_blob_from_id(struct drm_device *dev,
uint64_t blob_id,
ssize_t expected_size,
ssize_t expected_elem_size,
+ ssize_t max_size,
bool *replaced);
int drm_property_replace_global_blob(struct drm_device *dev,
struct drm_property_blob **replace,
diff --git a/include/drm/intel/display_parent_interface.h b/include/drm/intel/display_parent_interface.h
index 10c50b42844e..ce946859a3a9 100644
--- a/include/drm/intel/display_parent_interface.h
+++ b/include/drm/intel/display_parent_interface.h
@@ -7,9 +7,15 @@
#include <linux/types.h>
struct dma_fence;
+struct drm_crtc;
struct drm_device;
+struct drm_framebuffer;
+struct drm_gem_object;
+struct drm_plane_state;
struct drm_scanout_buffer;
+struct i915_vma;
struct intel_hdcp_gsc_context;
+struct intel_initial_plane_config;
struct intel_panic;
struct intel_stolen_node;
struct ref_tracker;
@@ -25,6 +31,14 @@ struct intel_display_hdcp_interface {
void (*gsc_context_free)(struct intel_hdcp_gsc_context *gsc_context);
};
+struct intel_display_initial_plane_interface {
+ void (*vblank_wait)(struct drm_crtc *crtc);
+ struct drm_gem_object *(*alloc_obj)(struct drm_device *drm, struct intel_initial_plane_config *plane_config);
+ int (*setup)(struct drm_plane_state *plane_state, struct intel_initial_plane_config *plane_config,
+ struct drm_framebuffer *fb, struct i915_vma *vma);
+ void (*config_fini)(struct intel_initial_plane_config *plane_configs);
+};
+
struct intel_display_irq_interface {
bool (*enabled)(struct drm_device *drm);
void (*synchronize)(struct drm_device *drm);
@@ -95,6 +109,9 @@ struct intel_display_parent_interface {
/** @hdcp: HDCP GSC interface */
const struct intel_display_hdcp_interface *hdcp;
+ /** @initial_plane: Initial plane interface */
+ const struct intel_display_initial_plane_interface *initial_plane;
+
/** @irq: IRQ interface */
const struct intel_display_irq_interface *irq;
diff --git a/include/drm/intel/intel_lb_mei_interface.h b/include/drm/intel/intel_lb_mei_interface.h
index d65be2cba2ab..0850738a30fc 100644
--- a/include/drm/intel/intel_lb_mei_interface.h
+++ b/include/drm/intel/intel_lb_mei_interface.h
@@ -53,7 +53,8 @@ enum intel_lb_status {
*/
struct intel_lb_component_ops {
/**
- * push_payload - Sends a payload to the authentication firmware
+ * @push_payload: Sends a payload to the authentication firmware
+ *
* @dev: Device struct corresponding to the mei device
* @type: Payload type (see &enum intel_lb_type)
* @flags: Payload flags bitmap (e.g. %INTEL_LB_FLAGS_IS_PERSISTENT)