summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_connector.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_connector.c')
-rw-r--r--drivers/gpu/drm/drm_connector.c127
1 files changed, 102 insertions, 25 deletions
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 7631f76e7f34..da39e7ff6965 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -20,6 +20,7 @@
* OF THIS SOFTWARE.
*/
+#include <drm/drm_auth.h>
#include <drm/drm_connector.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder.h>
@@ -279,7 +280,8 @@ int drm_connector_init(struct drm_device *dev,
drm_connector_get_cmdline_mode(connector);
/* We should add connectors at the end to avoid upsetting the connector
- * index too much. */
+ * index too much.
+ */
spin_lock_irq(&config->connector_list_lock);
list_add_tail(&connector->head, &config->connector_list);
config->num_connector++;
@@ -1958,11 +1960,11 @@ int drm_connector_set_path_property(struct drm_connector *connector,
int ret;
ret = drm_property_replace_global_blob(dev,
- &connector->path_blob_ptr,
- strlen(path) + 1,
- path,
- &connector->base,
- dev->mode_config.path_property);
+ &connector->path_blob_ptr,
+ strlen(path) + 1,
+ path,
+ &connector->base,
+ dev->mode_config.path_property);
return ret;
}
EXPORT_SYMBOL(drm_connector_set_path_property);
@@ -1988,11 +1990,11 @@ int drm_connector_set_tile_property(struct drm_connector *connector)
if (!connector->has_tile) {
ret = drm_property_replace_global_blob(dev,
- &connector->tile_blob_ptr,
- 0,
- NULL,
- &connector->base,
- dev->mode_config.tile_property);
+ &connector->tile_blob_ptr,
+ 0,
+ NULL,
+ &connector->base,
+ dev->mode_config.tile_property);
return ret;
}
@@ -2003,11 +2005,11 @@ int drm_connector_set_tile_property(struct drm_connector *connector)
connector->tile_h_size, connector->tile_v_size);
ret = drm_property_replace_global_blob(dev,
- &connector->tile_blob_ptr,
- strlen(tile) + 1,
- tile,
- &connector->base,
- dev->mode_config.tile_property);
+ &connector->tile_blob_ptr,
+ strlen(tile) + 1,
+ tile,
+ &connector->base,
+ dev->mode_config.tile_property);
return ret;
}
EXPORT_SYMBOL(drm_connector_set_tile_property);
@@ -2076,10 +2078,10 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
ret = drm_property_replace_global_blob(dev,
&connector->edid_blob_ptr,
- size,
- edid,
- &connector->base,
- dev->mode_config.edid_property);
+ size,
+ edid,
+ &connector->base,
+ dev->mode_config.edid_property);
if (ret)
return ret;
return drm_connector_set_tile_property(connector);
@@ -2151,6 +2153,75 @@ int drm_connector_attach_max_bpc_property(struct drm_connector *connector,
EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);
/**
+ * drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property
+ * @connector: connector to attach the property on.
+ *
+ * This is used to allow the userspace to send HDR Metadata to the
+ * driver.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_property *prop = dev->mode_config.hdr_output_metadata_property;
+
+ drm_object_attach_property(&connector->base, prop, 0);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);
+
+/**
+ * drm_connector_attach_colorspace_property - attach "Colorspace" property
+ * @connector: connector to attach the property on.
+ *
+ * This is used to allow the userspace to signal the output colorspace
+ * to the driver.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_colorspace_property(struct drm_connector *connector)
+{
+ struct drm_property *prop = connector->colorspace_property;
+
+ drm_object_attach_property(&connector->base, prop, DRM_MODE_COLORIMETRY_DEFAULT);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_colorspace_property);
+
+/**
+ * drm_connector_atomic_hdr_metadata_equal - checks if the hdr metadata changed
+ * @old_state: old connector state to compare
+ * @new_state: new connector state to compare
+ *
+ * This is used by HDR-enabled drivers to test whether the HDR metadata
+ * have changed between two different connector state (and thus probably
+ * requires a full blown mode change).
+ *
+ * Returns:
+ * True if the metadata are equal, False otherwise
+ */
+bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,
+ struct drm_connector_state *new_state)
+{
+ struct drm_property_blob *old_blob = old_state->hdr_output_metadata;
+ struct drm_property_blob *new_blob = new_state->hdr_output_metadata;
+
+ if (!old_blob || !new_blob)
+ return old_blob == new_blob;
+
+ if (old_blob->length != new_blob->length)
+ return false;
+
+ return !memcmp(old_blob->data, new_blob->data, old_blob->length);
+}
+EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);
+
+/**
* drm_connector_set_vrr_capable_property - sets the variable refresh rate
* capable property for a connector
* @connector: drm connector
@@ -2288,7 +2359,8 @@ int drm_connector_property_set_ioctl(struct drm_device *dev,
static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
{
/* For atomic drivers only state objects are synchronously updated and
- * protected by modeset locks, so check those first. */
+ * protected by modeset locks, so check those first.
+ */
if (connector->state)
return connector->state->best_encoder;
return connector->encoder;
@@ -2374,9 +2446,13 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
mutex_lock(&dev->mode_config.mutex);
if (out_resp->count_modes == 0) {
- connector->funcs->fill_modes(connector,
- dev->mode_config.max_width,
- dev->mode_config.max_height);
+ if (drm_is_current_master(file_priv))
+ connector->funcs->fill_modes(connector,
+ dev->mode_config.max_width,
+ dev->mode_config.max_height);
+ else
+ drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe",
+ connector->base.id, connector->name);
}
out_resp->mm_width = connector->display_info.width_mm;
@@ -2450,7 +2526,8 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
out_resp->encoder_id = 0;
/* Only grab properties after probing, to make sure EDID and other
- * properties reflect the latest status. */
+ * properties reflect the latest status.
+ */
ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,
(uint32_t __user *)(unsigned long)(out_resp->props_ptr),
(uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),