[PATCH RFC] drm: add broadcast rgb connector property for digital outputs

Russell King rmk+kernel at armlinux.org.uk
Wed Jul 4 21:36:07 UTC 2018


Add core DRM support for the i915 "Broadcast RGB" property, which
controls the selection of the RGB quantization range in the digital
domain.  For 8bpc, this selects between limited (16 to 235), full
(0 to 255) range, or automatically select depending on the mode.

Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
---
As described in the commit description, this is modelled on the i915
property, and uses exactly the same strings as the i915 version.

Some discussion points:

1. do we wish to call the additional structure members "broadcast_rgb"
   or would "rgb_quantization_range" be more appropriate for what it is?

2. should drm_connector_create_broadcast_rgb_property() create the
   mode_config property when required and attach it to the connector,
   or should drm_connector_create_standard_properties() create the
   property, and have drm_connector_attach_broadcast_rgb_property()
   attach it to the connector instead?

3. should we pass a bitmask of the supported types in the same way that
   the YCbCr properties do and create per-connector properties?

 drivers/gpu/drm/drm_atomic.c        |  6 ++++
 drivers/gpu/drm/drm_atomic_helper.c |  4 ++-
 drivers/gpu/drm/drm_color_mgmt.c    | 62 +++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h         | 27 ++++++++++++++++
 include/drm/drm_mode_config.h       |  7 +++++
 5 files changed, 105 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index d5cefb1cb2a2..4aa9ddb84aad 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1415,6 +1415,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 
 		return set_out_fence_for_connector(state->state, connector,
 						   fence_ptr);
+	} else if (property == config->broadcast_rgb_property) {
+		state->broadcast_rgb = val;
 	} else if (connector->funcs->atomic_set_property) {
 		return connector->funcs->atomic_set_property(connector,
 				state, property, val);
@@ -1435,6 +1437,8 @@ static void drm_atomic_connector_print_state(struct drm_printer *p,
 
 	drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
 	drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
+	drm_printf(p, "\tbroadcast_rgb=%s\n",
+		   drm_get_broadcast_rgb_name(state->broadcast_rgb));
 
 	if (connector->funcs->atomic_print_state)
 		connector->funcs->atomic_print_state(p, state);
@@ -1506,6 +1510,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = 0;
 	} else if (property == config->writeback_out_fence_ptr_property) {
 		*val = 0;
+	} else if (property == config->broadcast_rgb_property) {
+		*val = state->broadcast_rgb;
 	} else if (connector->funcs->atomic_get_property) {
 		return connector->funcs->atomic_get_property(connector,
 				state, property, val);
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 8008a7de2e10..5540e99923fb 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3630,8 +3630,10 @@ void
 __drm_atomic_helper_connector_reset(struct drm_connector *connector,
 				    struct drm_connector_state *conn_state)
 {
-	if (conn_state)
+	if (conn_state) {
 		conn_state->connector = connector;
+		conn_state->broadcast_rgb = DRM_BROADCAST_RGB_AUTO;
+	}
 
 	connector->state = conn_state;
 }
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index b97e2de2c029..b85ea3eabe2c 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -102,6 +102,14 @@
  * 	Optional plane enum property to support different non RGB
  * 	color parameter ranges. The driver can provide a subset of
  * 	standard enum values supported by the DRM plane.
+ *
+ * Support for output RGB color range is controlled through the
+ * &drm_connector specific "Broadcast RGB" property.  This is created
+ * and setup by calling drm_connector_create_broadcast_rgb_property().
+ *
+ * "Broadcast RGB"
+ *	Optional connector property to support different RGB output
+ *	ranges.
  */
 
 /**
@@ -472,3 +480,57 @@ int drm_plane_create_color_properties(struct drm_plane *plane,
 	return 0;
 }
 EXPORT_SYMBOL(drm_plane_create_color_properties);
+
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
+	{ DRM_BROADCAST_RGB_AUTO, "Automatic" },
+	{ DRM_BROADCAST_RGB_FULL, "Full" },
+	{ DRM_BROADCAST_RGB_LIMITED, "Limited 16:235" },
+};
+
+/**
+ * drm_get_broadcast_rgb_name - return a string for the broadcast rgb property
+ * @mode: broadcast rgb mode
+ *
+ * Return a const pointer to a string defining the RGB quantization range.
+ */
+const char *drm_get_broadcast_rgb_name(enum drm_broadcast_rgb_mode mode)
+{
+	if (WARN_ON(mode >= ARRAY_SIZE(broadcast_rgb_names)))
+		return "unknown";
+	return broadcast_rgb_names[mode].name;
+}
+
+/**
+ * drm_connector_create_broadcast_rgb_property - add RGB range property
+ * @connector: connector object to attach RGB range property to
+ * @mode: default mode for the RGB output range
+ *
+ * Create if necessary the "Broadcast RGB" property and attach it to
+ * @connector.
+ */
+int drm_connector_create_broadcast_rgb_property(struct drm_connector *connector,
+				enum drm_broadcast_rgb_mode mode)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	if (!dev->mode_config.broadcast_rgb_property) {
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
+					"Broadcast RGB", broadcast_rgb_names,
+					ARRAY_SIZE(broadcast_rgb_names));
+		if (!prop)
+			return -ENOMEM;
+
+		dev->mode_config.broadcast_rgb_property = prop;
+	}
+
+	drm_object_attach_property(&connector->base,
+				   dev->mode_config.broadcast_rgb_property,
+				   mode);
+
+	if (connector->state)
+		connector->state->broadcast_rgb = mode;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_create_broadcast_rgb_property);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index bf0f0f0786d3..70458c2bf4b0 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -206,6 +206,23 @@ enum drm_panel_orientation {
 };
 
 /**
+ * enum drm_broadcast_rgb_mode - broadcast (output) rgb range
+ *
+ * For digital outputs, this enum describes the quantization range of RGB
+ * values to be supplied to the connected sink.
+ *
+ * DRM_BROADCAST_RGB_AUTO:    Automatically select, according to the display
+ *			      mode, limited or full quantization range.
+ * DRM_BROADCAST_RGB_FULL:    Full (eg, 0 to 255) quantization range RGB.
+ * DRM_BROADCAST_RGB_LIMITED: Limited (eg, 16 to 235) quantization range RGB.
+ */
+enum drm_broadcast_rgb_mode {
+	DRM_BROADCAST_RGB_AUTO,
+	DRM_BROADCAST_RGB_FULL,
+	DRM_BROADCAST_RGB_LIMITED,
+};
+
+/**
  * struct drm_display_info - runtime data about the connected sink
  *
  * Describes a given display (e.g. CRT or flat panel) and its limitations. For
@@ -450,6 +467,12 @@ struct drm_connector_state {
 	 * drm_writeback_signal_completion()
 	 */
 	struct drm_writeback_job *writeback_job;
+
+	/**
+	 * @broadcast_rgb: Connector property to control the RGB
+	 * quantization range.
+	 */
+	enum drm_broadcast_rgb_mode broadcast_rgb;
 };
 
 /**
@@ -1114,6 +1137,8 @@ const char *drm_get_dvi_i_select_name(int val);
 const char *drm_get_tv_subconnector_name(int val);
 const char *drm_get_tv_select_name(int val);
 const char *drm_get_content_protection_name(int val);
+const char *drm_get_broadcast_rgb_name(enum drm_broadcast_rgb_mode mode);
+
 
 int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 int drm_mode_create_tv_properties(struct drm_device *dev,
@@ -1131,6 +1156,8 @@ void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
 					 const struct drm_connector_state *conn_state);
 
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
+int drm_connector_create_broadcast_rgb_property(struct drm_connector *connector,
+					enum drm_broadcast_rgb_mode mode);
 
 int drm_mode_connector_set_path_property(struct drm_connector *connector,
 					 const char *path);
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index a0b202e1d69a..609922529368 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -807,6 +807,13 @@ struct drm_mode_config {
 	 */
 	struct drm_property *writeback_out_fence_ptr_property;
 
+	/**
+	 * @broadcast_rgb_property: Optional connector property indicating
+	 * whether the output RGB should be automatically selected, limited
+	 * range (16-235) or full range (0-255).
+	 */
+	struct drm_property *broadcast_rgb_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.7.4



More information about the dri-devel mailing list