---
drivers/gpu/drm/drm_atomic_uapi.c | 8 +++
drivers/gpu/drm/drm_color_mgmt.c | 90 +++++++++++++++++++++++++++++++
include/drm/drm_color_mgmt.h | 7 +++
include/drm/drm_connector.h | 17 ++++++
include/drm/drm_mode_config.h | 14 +++++
5 files changed, 136 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c
b/drivers/gpu/drm/drm_atomic_uapi.c
index ecc73d52bfae..12379673dea1 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -774,6 +774,10 @@ 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->writeback_color_encoding) {
+ state->writeback_color_encoding = val;
+ } else if (property == config->writeback_color_range) {
+ state->writeback_color_range = val;
} else if (property == connector->max_bpc_property) {
state->max_requested_bpc = val;
} else if (property == connector->privacy_screen_sw_state_property) {
@@ -859,6 +863,10 @@ 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->writeback_color_encoding) {
+ *val = state->writeback_color_encoding;
+ } else if (property == config->writeback_color_range) {
+ *val = state->writeback_color_range;
} else if (property == connector->max_bpc_property) {
*val = state->max_requested_bpc;
} else if (property == connector->privacy_screen_sw_state_property) {
diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 37a3270bc3c2..04444c215bf4 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -29,6 +29,7 @@
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_print.h>
+#include <drm/drm_writeback.h>
#include <kunit/visibility.h>
#include "drm_crtc_internal.h"
@@ -592,6 +593,95 @@ int drm_plane_create_color_properties(struct drm_plane
*plane,
}
EXPORT_SYMBOL(drm_plane_create_color_properties);
+/**
+ * drm_writeback_create_color_properties - color encoding related writeback
connector properties
+ * @wb_connector: writeback connector object
+ * @supported_encodings: bitfield indicating supported color encodings
+ * @supported_ranges: bitfileld indicating supported color ranges
+ * @default_encoding: default color encoding
+ * @default_range: default color range
+ *
+ * Create and attach writeback connector specific WRITEBACK_COLOR_ENCODING and
+ * WRITEBACK_COLOR_RANGE properties to @wb_connector. The supported encodings
+ * and ranges should be provided in supported_encodings and supported_ranges
+ * bitmasks. Each bit set in the bitmask indicates that its number as enum
+ * value is supported.
+ */
+int drm_writeback_create_color_properties(struct drm_writeback_connector
*wb_connector,
+ u32 supported_encodings,
+ u32 supported_ranges,
+ enum drm_color_encoding
default_encoding,
+ enum drm_color_range default_range)
+{
+ struct drm_connector *connector = &wb_connector->base;
+ struct drm_device *dev = connector->dev;
+ struct drm_property *prop;
+ struct drm_prop_enum_list enum_list[MAX_T(int, DRM_COLOR_ENCODING_MAX,
+ DRM_COLOR_RANGE_MAX)];
+ int i, len;
+
+ if (WARN_ON(supported_encodings == 0 ||
+ (supported_encodings & -BIT(DRM_COLOR_ENCODING_MAX)) != 0 ||
+ (supported_encodings & BIT(default_encoding)) == 0))
+ return -EINVAL;
+
+ if (WARN_ON(supported_ranges == 0 ||
+ (supported_ranges & -BIT(DRM_COLOR_RANGE_MAX)) != 0 ||
+ (supported_ranges & BIT(default_range)) == 0))
+ return -EINVAL;
+
+ if (!dev->mode_config.writeback_color_encoding) {
+ len = 0;
+ for (i = 0; i < DRM_COLOR_ENCODING_MAX; i++) {
+ if ((supported_encodings & BIT(i)) == 0)
+ continue;
+
+ enum_list[len].type = i;
+ enum_list[len].name = color_encoding_name[i];
+ len++;
+ }
+
+ prop = drm_property_create_enum(dev, 0,
+ "WRITEBACK_COLOR_ENCODING",
+ enum_list, len);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.writeback_color_encoding = prop;
+ }
+
+ drm_object_attach_property(&connector->base,
+ dev->mode_config.writeback_color_encoding,
+ default_encoding);
+ if (connector->state)
+ connector->state->writeback_color_encoding = default_encoding;
+
+ if (!dev->mode_config.writeback_color_range) {
+ len = 0;
+ for (i = 0; i < DRM_COLOR_RANGE_MAX; i++) {
+ if ((supported_ranges & BIT(i)) == 0)
+ continue;
+
+ enum_list[len].type = i;
+ enum_list[len].name = color_range_name[i];
+ len++;
+ }
+
+ prop = drm_property_create_enum(dev, 0, "WRITEBACK_COLOR_RANGE",
+ enum_list, len);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.writeback_color_range = prop;
+ }
+ drm_object_attach_property(&connector->base,
+ dev->mode_config.writeback_color_range,
+ default_range);
+ if (connector->state)
+ connector->state->writeback_color_range = default_range;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_writeback_create_color_properties);
+
/**
* drm_color_lut_check - check validity of lookup table
* @lut: property blob containing LUT to check
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index 6cb577f6dba6..60146e3063fd 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -29,6 +29,7 @@
struct drm_crtc;
struct drm_plane;
+struct drm_writeback_connector;
/**
* drm_color_lut_extract - clamp and round LUT entries
@@ -91,6 +92,12 @@ int drm_plane_create_color_properties(struct drm_plane
*plane,
enum drm_color_encoding default_encoding,
enum drm_color_range default_range);
+int drm_writeback_create_color_properties(struct drm_writeback_connector *wb_connector,
+ u32 supported_encodings,
+ u32 supported_ranges,
+ enum drm_color_encoding
default_encoding,
+ enum drm_color_range default_range);
+
/**
* enum drm_color_lut_tests - hw-specific LUT tests to perform
*
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 8f34f4b8183d..178bfbcb13e3 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -28,6 +28,7 @@
#include <linux/ctype.h>
#include <linux/hdmi.h>
#include <linux/notifier.h>
+#include <drm/drm_color_mgmt.h>
#include <drm/drm_mode_object.h>
#include <drm/drm_util.h>
#include <drm/drm_property.h>
@@ -1120,6 +1121,22 @@ struct drm_connector_state {
*/
struct drm_writeback_job *writeback_job;
+ /**
+ * @writeback_color_encoding:
+ *
+ * Color encoding for non RGB formats used by writeback connectors.
+ * See also: drm_writeback_create_color_properties()
+ */
+ enum drm_color_encoding writeback_color_encoding;
+
+ /**
+ * @writeback_color_range:
+ *
+ * Color encoding for non RGB formats used by writeback connectors.
+ * See also: drm_writeback_create_color_properties()
+ */
+ enum drm_color_range writeback_color_range;
+
/**
* @max_requested_bpc: Connector property to limit the maximum bit
* depth of the pixels.
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 2e848b816218..1d2a7cb6d410 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -863,6 +863,20 @@ struct drm_mode_config {
*/
struct drm_property *writeback_out_fence_ptr_property;
+ /**
+ * @writeback_color_encoding: Optional property for writeback
+ * connectors, color encoding for non RGB formats.
+ * See also: drm_writeback_create_color_properties()
+ */
+ struct drm_property *writeback_color_encoding;
+
+ /**
+ * @writeback_color_range: Optional property for writeback connectors,
+ * color range for non RGB formats.
+ * See also: drm_writeback_create_color_properties()
+ */
+ struct drm_property *writeback_color_range;
+
/**
* @hdr_output_metadata_property: Connector property containing hdr
* metatada. This will be provided by userspace compositors based