aboutsummaryrefslogtreecommitdiffstats
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.c401
1 files changed, 320 insertions, 81 deletions
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index dd40eff0911c..2166000ed057 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -92,6 +92,7 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {
{ DRM_MODE_CONNECTOR_DSI, "DSI" },
{ DRM_MODE_CONNECTOR_DPI, "DPI" },
{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },
+ { DRM_MODE_CONNECTOR_SPI, "SPI" },
};
void drm_connector_ida_init(void)
@@ -139,8 +140,8 @@ static void drm_connector_get_cmdline_mode(struct drm_connector *connector)
connector->force = mode->force;
}
- DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
- connector->name,
+ DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n",
+ connector->name, mode->name,
mode->xres, mode->yres,
mode->refresh_specified ? mode->refresh : 60,
mode->rb ? " reduced blanking" : "",
@@ -245,6 +246,7 @@ int drm_connector_init(struct drm_device *dev,
INIT_LIST_HEAD(&connector->modes);
mutex_init(&connector->mutex);
connector->edid_blob_ptr = NULL;
+ connector->tile_blob_ptr = NULL;
connector->status = connector_status_unknown;
connector->display_info.panel_orientation =
DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
@@ -272,6 +274,9 @@ int drm_connector_init(struct drm_device *dev,
drm_object_attach_property(&connector->base,
config->non_desktop_property,
0);
+ drm_object_attach_property(&connector->base,
+ config->tile_property,
+ 0);
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
@@ -293,6 +298,41 @@ out_put:
EXPORT_SYMBOL(drm_connector_init);
/**
+ * drm_connector_init_with_ddc - Init a preallocated connector
+ * @dev: DRM device
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @connector_type: user visible type of the connector
+ * @ddc: pointer to the associated ddc adapter
+ *
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects.
+ *
+ * Ensures that the ddc field of the connector is correctly set.
+ *
+ * Returns:
+ * Zero on success, error code on failure.
+ */
+int drm_connector_init_with_ddc(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type,
+ struct i2c_adapter *ddc)
+{
+ int ret;
+
+ ret = drm_connector_init(dev, connector, funcs, connector_type);
+ if (ret)
+ return ret;
+
+ /* provide ddc symlink in sysfs */
+ connector->ddc = ddc;
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_connector_init_with_ddc);
+
+/**
* drm_connector_attach_edid_property - attach edid property.
* @connector: the connector
*
@@ -325,8 +365,6 @@ EXPORT_SYMBOL(drm_connector_attach_edid_property);
int drm_connector_attach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder)
{
- int i;
-
/*
* In the past, drivers have attempted to model the static association
* of connector to encoder in simple connector/encoder devices using a
@@ -341,18 +379,15 @@ int drm_connector_attach_encoder(struct drm_connector *connector,
if (WARN_ON(connector->encoder))
return -EINVAL;
- for (i = 0; i < ARRAY_SIZE(connector->encoder_ids); i++) {
- if (connector->encoder_ids[i] == 0) {
- connector->encoder_ids[i] = encoder->base.id;
- return 0;
- }
- }
- return -ENOMEM;
+ connector->possible_encoders |= drm_encoder_mask(encoder);
+
+ return 0;
}
EXPORT_SYMBOL(drm_connector_attach_encoder);
/**
- * drm_connector_has_possible_encoder - check if the connector and encoder are assosicated with each other
+ * drm_connector_has_possible_encoder - check if the connector and encoder are
+ * associated with each other
* @connector: the connector
* @encoder: the encoder
*
@@ -362,15 +397,7 @@ EXPORT_SYMBOL(drm_connector_attach_encoder);
bool drm_connector_has_possible_encoder(struct drm_connector *connector,
struct drm_encoder *encoder)
{
- struct drm_encoder *enc;
- int i;
-
- drm_connector_for_each_possible_encoder(connector, enc, i) {
- if (enc == encoder)
- return true;
- }
-
- return false;
+ return connector->possible_encoders & drm_encoder_mask(encoder);
}
EXPORT_SYMBOL(drm_connector_has_possible_encoder);
@@ -440,7 +467,10 @@ EXPORT_SYMBOL(drm_connector_cleanup);
* drm_connector_register - register a connector
* @connector: the connector to register
*
- * Register userspace interfaces for a connector
+ * Register userspace interfaces for a connector. Only call this for connectors
+ * which can be hotplugged after drm_dev_register() has been called already,
+ * e.g. DP MST connectors. All other connectors will be registered automatically
+ * when calling drm_dev_register().
*
* Returns:
* Zero on success, error code on failure.
@@ -460,10 +490,7 @@ int drm_connector_register(struct drm_connector *connector)
if (ret)
goto unlock;
- ret = drm_debugfs_connector_add(connector);
- if (ret) {
- goto err_sysfs;
- }
+ drm_debugfs_connector_add(connector);
if (connector->funcs->late_register) {
ret = connector->funcs->late_register(connector);
@@ -478,7 +505,6 @@ int drm_connector_register(struct drm_connector *connector)
err_debugfs:
drm_debugfs_connector_remove(connector);
-err_sysfs:
drm_sysfs_connector_remove(connector);
unlock:
mutex_unlock(&connector->mutex);
@@ -490,7 +516,10 @@ EXPORT_SYMBOL(drm_connector_register);
* drm_connector_unregister - unregister a connector
* @connector: the connector to unregister
*
- * Unregister userspace interfaces for a connector
+ * Unregister userspace interfaces for a connector. Only call this for
+ * connectors which have registered explicitly by calling drm_dev_register(),
+ * since connectors are unregistered automatically when drm_dev_unregister() is
+ * called.
*/
void drm_connector_unregister(struct drm_connector *connector)
{
@@ -683,7 +712,7 @@ void drm_connector_list_iter_end(struct drm_connector_list_iter *iter)
__drm_connector_put_safe(iter->conn);
spin_unlock_irqrestore(&config->connector_list_lock, flags);
}
- lock_release(&connector_list_iter_dep_map, 0, _RET_IP_);
+ lock_release(&connector_list_iter_dep_map, _RET_IP_);
}
EXPORT_SYMBOL(drm_connector_list_iter_end);
@@ -819,12 +848,64 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
drm_tv_subconnector_enum_list)
-static struct drm_prop_enum_list drm_cp_enum_list[] = {
- { DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
- { DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
- { DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+static const struct drm_prop_enum_list hdmi_colorspaces[] = {
+ /* For Default case, driver will set the colorspace */
+ { DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
+ /* Standard Definition Colorimetry based on CEA 861 */
+ { DRM_MODE_COLORIMETRY_SMPTE_170M_YCC, "SMPTE_170M_YCC" },
+ { DRM_MODE_COLORIMETRY_BT709_YCC, "BT709_YCC" },
+ /* Standard Definition Colorimetry based on IEC 61966-2-4 */
+ { DRM_MODE_COLORIMETRY_XVYCC_601, "XVYCC_601" },
+ /* High Definition Colorimetry based on IEC 61966-2-4 */
+ { DRM_MODE_COLORIMETRY_XVYCC_709, "XVYCC_709" },
+ /* Colorimetry based on IEC 61966-2-1/Amendment 1 */
+ { DRM_MODE_COLORIMETRY_SYCC_601, "SYCC_601" },
+ /* Colorimetry based on IEC 61966-2-5 [33] */
+ { DRM_MODE_COLORIMETRY_OPYCC_601, "opYCC_601" },
+ /* Colorimetry based on IEC 61966-2-5 */
+ { DRM_MODE_COLORIMETRY_OPRGB, "opRGB" },
+ /* Colorimetry based on ITU-R BT.2020 */
+ { DRM_MODE_COLORIMETRY_BT2020_CYCC, "BT2020_CYCC" },
+ /* Colorimetry based on ITU-R BT.2020 */
+ { DRM_MODE_COLORIMETRY_BT2020_RGB, "BT2020_RGB" },
+ /* Colorimetry based on ITU-R BT.2020 */
+ { DRM_MODE_COLORIMETRY_BT2020_YCC, "BT2020_YCC" },
+ /* Added as part of Additional Colorimetry Extension in 861.G */
+ { DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65, "DCI-P3_RGB_D65" },
+ { DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, "DCI-P3_RGB_Theater" },
+};
+
+/*
+ * As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry
+ * Format Table 2-120
+ */
+static const struct drm_prop_enum_list dp_colorspaces[] = {
+ /* For Default case, driver will set the colorspace */
+ { DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
+ { DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED, "RGB_Wide_Gamut_Fixed_Point" },
+ /* Colorimetry based on scRGB (IEC 61966-2-2) */
+ { DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT, "RGB_Wide_Gamut_Floating_Point" },
+ /* Colorimetry based on IEC 61966-2-5 */
+ { DRM_MODE_COLORIMETRY_OPRGB, "opRGB" },
+ /* Colorimetry based on SMPTE RP 431-2 */
+ { DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65, "DCI-P3_RGB_D65" },
+ /* Colorimetry based on ITU-R BT.2020 */
+ { DRM_MODE_COLORIMETRY_BT2020_RGB, "BT2020_RGB" },
+ { DRM_MODE_COLORIMETRY_BT601_YCC, "BT601_YCC" },
+ { DRM_MODE_COLORIMETRY_BT709_YCC, "BT709_YCC" },
+ /* Standard Definition Colorimetry based on IEC 61966-2-4 */
+ { DRM_MODE_COLORIMETRY_XVYCC_601, "XVYCC_601" },
+ /* High Definition Colorimetry based on IEC 61966-2-4 */
+ { DRM_MODE_COLORIMETRY_XVYCC_709, "XVYCC_709" },
+ /* Colorimetry based on IEC 61966-2-1/Amendment 1 */
+ { DRM_MODE_COLORIMETRY_SYCC_601, "SYCC_601" },
+ /* Colorimetry based on IEC 61966-2-5 [33] */
+ { DRM_MODE_COLORIMETRY_OPYCC_601, "opYCC_601" },
+ /* Colorimetry based on ITU-R BT.2020 */
+ { DRM_MODE_COLORIMETRY_BT2020_CYCC, "BT2020_CYCC" },
+ /* Colorimetry based on ITU-R BT.2020 */
+ { DRM_MODE_COLORIMETRY_BT2020_YCC, "BT2020_YCC" },
};
-DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
/**
* DOC: standard connector properties
@@ -927,10 +1008,113 @@ DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
* - If the state is DESIRED, kernel should attempt to re-authenticate the
* link whenever possible. This includes across disable/enable, dpms,
* hotplug, downstream device changes, link status failures, etc..
- * - Userspace is responsible for polling the property to determine when
- * the value transitions from ENABLED to DESIRED. This signifies the link
- * is no longer protected and userspace should take appropriate action
- * (whatever that might be).
+ * - Kernel sends uevent with the connector id and property id through
+ * @drm_hdcp_update_content_protection, upon below kernel triggered
+ * scenarios:
+ *
+ * - DESIRED -> ENABLED (authentication success)
+ * - ENABLED -> DESIRED (termination of authentication)
+ * - Please note no uevents for userspace triggered property state changes,
+ * which can't fail such as
+ *
+ * - DESIRED/ENABLED -> UNDESIRED
+ * - UNDESIRED -> DESIRED
+ * - Userspace is responsible for polling the property or listen to uevents
+ * to determine when the value transitions from ENABLED to DESIRED.
+ * This signifies the link is no longer protected and userspace should
+ * take appropriate action (whatever that might be).
+ *
+ * HDCP Content Type:
+ * This Enum property is used by the userspace to declare the content type
+ * of the display stream, to kernel. Here display stream stands for any
+ * display content that userspace intended to display through HDCP
+ * encryption.
+ *
+ * Content Type of a stream is decided by the owner of the stream, as
+ * "HDCP Type0" or "HDCP Type1".
+ *
+ * The value of the property can be one of the below:
+ * - "HDCP Type0": DRM_MODE_HDCP_CONTENT_TYPE0 = 0
+ * - "HDCP Type1": DRM_MODE_HDCP_CONTENT_TYPE1 = 1
+ *
+ * When kernel starts the HDCP authentication (see "Content Protection"
+ * for details), it uses the content type in "HDCP Content Type"
+ * for performing the HDCP authentication with the display sink.
+ *
+ * Please note in HDCP spec versions, a link can be authenticated with
+ * HDCP 2.2 for Content Type 0/Content Type 1. Where as a link can be
+ * authenticated with HDCP1.4 only for Content Type 0(though it is implicit
+ * in nature. As there is no reference for Content Type in HDCP1.4).
+ *
+ * HDCP2.2 authentication protocol itself takes the "Content Type" as a
+ * parameter, which is a input for the DP HDCP2.2 encryption algo.
+ *
+ * In case of Type 0 content protection request, kernel driver can choose
+ * either of HDCP spec versions 1.4 and 2.2. When HDCP2.2 is used for
+ * "HDCP Type 0", a HDCP 2.2 capable repeater in the downstream can send
+ * that content to a HDCP 1.4 authenticated HDCP sink (Type0 link).
+ * But if the content is classified as "HDCP Type 1", above mentioned
+ * HDCP 2.2 repeater wont send the content to the HDCP sink as it can't
+ * authenticate the HDCP1.4 capable sink for "HDCP Type 1".
+ *
+ * Please note userspace can be ignorant of the HDCP versions used by the
+ * kernel driver to achieve the "HDCP Content Type".
+ *
+ * At current scenario, classifying a content as Type 1 ensures that the
+ * content will be displayed only through the HDCP2.2 encrypted link.
+ *
+ * Note that the HDCP Content Type property is introduced at HDCP 2.2, and
+ * defaults to type 0. It is only exposed by drivers supporting HDCP 2.2
+ * (hence supporting Type 0 and Type 1). Based on how next versions of
+ * HDCP specs are defined content Type could be used for higher versions
+ * too.
+ *
+ * If content type is changed when "Content Protection" is not UNDESIRED,
+ * then kernel will disable the HDCP and re-enable with new type in the
+ * same atomic commit. And when "Content Protection" is ENABLED, it means
+ * that link is HDCP authenticated and encrypted, for the transmission of
+ * the Type of stream mentioned at "HDCP Content Type".
+ *
+ * HDR_OUTPUT_METADATA:
+ * Connector property to enable userspace to send HDR Metadata to
+ * driver. This metadata is based on the composition and blending
+ * policies decided by user, taking into account the hardware and
+ * sink capabilities. The driver gets this metadata and creates a
+ * Dynamic Range and Mastering Infoframe (DRM) in case of HDMI,
+ * SDP packet (Non-audio INFOFRAME SDP v1.3) for DP. This is then
+ * sent to sink. This notifies the sink of the upcoming frame's Color
+ * Encoding and Luminance parameters.
+ *
+ * Userspace first need to detect the HDR capabilities of sink by
+ * reading and parsing the EDID. Details of HDR metadata for HDMI
+ * are added in CTA 861.G spec. For DP , its defined in VESA DP
+ * Standard v1.4. It needs to then get the metadata information
+ * of the video/game/app content which are encoded in HDR (basically
+ * using HDR transfer functions). With this information it needs to
+ * decide on a blending policy and compose the relevant
+ * layers/overlays into a common format. Once this blending is done,
+ * userspace will be aware of the metadata of the composed frame to
+ * be send to sink. It then uses this property to communicate this
+ * metadata to driver which then make a Infoframe packet and sends
+ * to sink based on the type of encoder connected.
+ *
+ * Userspace will be responsible to do Tone mapping operation in case:
+ * - Some layers are HDR and others are SDR
+ * - HDR layers luminance is not same as sink
+ *
+ * It will even need to do colorspace conversion and get all layers
+ * to one common colorspace for blending. It can use either GL, Media
+ * or display engine to get this done based on the capabilties of the
+ * associated hardware.
+ *
+ * Driver expects metadata to be put in &struct hdr_output_metadata
+ * structure from userspace. This is received as blob and stored in
+ * &drm_connector_state.hdr_output_metadata. It parses EDID and saves the
+ * sink metadata in &struct hdr_sink_metadata, as
+ * &drm_connector.hdr_sink_metadata. Driver uses
+ * drm_hdmi_infoframe_set_hdr_metadata() helper to set the HDR metadata,
+ * hdmi_drm_infoframe_pack() to pack the infoframe as per spec, in case of
+ * HDMI encoder.
*
* max bpc:
* This range property is used by userspace to limit the bit depth. When
@@ -1027,6 +1211,12 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.non_desktop_property = prop;
+ prop = drm_property_create(dev, DRM_MODE_PROP_BLOB,
+ "HDR_OUTPUT_METADATA", 0);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.hdr_output_metadata_property = prop;
+
return 0;
}
@@ -1385,12 +1575,6 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
*
* The driver may place further restrictions within these minimum
* and maximum bounds.
- *
- * The semantics for the vertical blank timestamp differ when
- * variable refresh rate is active. The vertical blank timestamp
- * is defined to be an estimate using the current mode's fixed
- * refresh rate timings. The semantics for the page-flip event
- * timestamp remain the same.
*/
/**
@@ -1485,67 +1669,117 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
/**
- * drm_connector_attach_content_protection_property - attach content protection
- * property
+ * drm_mode_create_aspect_ratio_property - create aspect ratio property
+ * @dev: DRM device
*
- * @connector: connector to attach CP property on.
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
*
- * This is used to add support for content protection on select connectors.
- * Content Protection is intentionally vague to allow for different underlying
- * technologies, however it is most implemented by HDCP.
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
+{
+ if (dev->mode_config.aspect_ratio_property)
+ return 0;
+
+ dev->mode_config.aspect_ratio_property =
+ drm_property_create_enum(dev, 0, "aspect ratio",
+ drm_aspect_ratio_enum_list,
+ ARRAY_SIZE(drm_aspect_ratio_enum_list));
+
+ if (dev->mode_config.aspect_ratio_property == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
+
+/**
+ * DOC: standard connector properties
*
- * The content protection will be set to &drm_connector_state.content_protection
+ * Colorspace:
+ * This property helps select a suitable colorspace based on the sink
+ * capability. Modern sink devices support wider gamut like BT2020.
+ * This helps switch to BT2020 mode if the BT2020 encoded video stream
+ * is being played by the user, same for any other colorspace. Thereby
+ * giving a good visual experience to users.
+ *
+ * The expectation from userspace is that it should parse the EDID
+ * and get supported colorspaces. Use this property and switch to the
+ * one supported. Sink supported colorspaces should be retrieved by
+ * userspace from EDID and driver will not explicitly expose them.
+ *
+ * Basically the expectation from userspace is:
+ * - Set up CRTC DEGAMMA/CTM/GAMMA to convert to some sink
+ * colorspace
+ * - Set this new property to let the sink know what it
+ * converted the CRTC output to.
+ * - This property is just to inform sink what colorspace
+ * source is trying to drive.
+ *
+ * Because between HDMI and DP have different colorspaces,
+ * drm_mode_create_hdmi_colorspace_property() is used for HDMI connector and
+ * drm_mode_create_dp_colorspace_property() is used for DP connector.
+ */
+
+/**
+ * drm_mode_create_hdmi_colorspace_property - create hdmi colorspace property
+ * @connector: connector to create the Colorspace property on.
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * HDMI connectors.
*
* Returns:
- * Zero on success, negative errno on failure.
+ * Zero on success, negative errono on failure.
*/
-int drm_connector_attach_content_protection_property(
- struct drm_connector *connector)
+int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
- struct drm_property *prop;
- prop = drm_property_create_enum(dev, 0, "Content Protection",
- drm_cp_enum_list,
- ARRAY_SIZE(drm_cp_enum_list));
- if (!prop)
- return -ENOMEM;
+ if (connector->colorspace_property)
+ return 0;
- drm_object_attach_property(&connector->base, prop,
- DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
+ connector->colorspace_property =
+ drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Colorspace",
+ hdmi_colorspaces,
+ ARRAY_SIZE(hdmi_colorspaces));
- connector->content_protection_property = prop;
+ if (!connector->colorspace_property)
+ return -ENOMEM;
return 0;
}
-EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
+EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property);
/**
- * drm_mode_create_aspect_ratio_property - create aspect ratio property
- * @dev: DRM device
+ * drm_mode_create_dp_colorspace_property - create dp colorspace property
+ * @connector: connector to create the Colorspace property on.
*
* Called by a driver the first time it's needed, must be attached to desired
- * connectors.
+ * DP connectors.
*
* Returns:
- * Zero on success, negative errno on failure.
+ * Zero on success, negative errono on failure.
*/
-int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
+int drm_mode_create_dp_colorspace_property(struct drm_connector *connector)
{
- if (dev->mode_config.aspect_ratio_property)
+ struct drm_device *dev = connector->dev;
+
+ if (connector->colorspace_property)
return 0;
- dev->mode_config.aspect_ratio_property =
- drm_property_create_enum(dev, 0, "aspect ratio",
- drm_aspect_ratio_enum_list,
- ARRAY_SIZE(drm_aspect_ratio_enum_list));
+ connector->colorspace_property =
+ drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Colorspace",
+ dp_colorspaces,
+ ARRAY_SIZE(dp_colorspaces));
- if (dev->mode_config.aspect_ratio_property == NULL)
+ if (!connector->colorspace_property)
return -ENOMEM;
return 0;
}
-EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
+EXPORT_SYMBOL(drm_mode_create_dp_colorspace_property);
/**
* drm_mode_create_content_type_property - create content type property
@@ -1634,6 +1868,8 @@ EXPORT_SYMBOL(drm_connector_set_path_property);
* This looks up the tile information for a connector, and creates a
* property for userspace to parse if it exists. The property is of
* the form of 8 integers using ':' as a separator.
+ * This is used for dual port tiled displays with DisplayPort SST
+ * or DisplayPort MST connectors.
*
* Returns:
* Zero on success, errno on failure.
@@ -1677,6 +1913,9 @@ EXPORT_SYMBOL(drm_connector_set_tile_property);
*
* This function creates a new blob modeset object and assigns its id to the
* connector's edid property.
+ * Since we also parse tile information from EDID's displayID block, we also
+ * set the connector's tile property here. See drm_connector_set_tile_property()
+ * for more details.
*
* Returns:
* Zero on success, negative errno on failure.
@@ -1718,7 +1957,9 @@ int drm_connector_update_edid_property(struct drm_connector *connector,
edid,
&connector->base,
dev->mode_config.edid_property);
- return ret;
+ if (ret)
+ return ret;
+ return drm_connector_set_tile_property(connector);
}
EXPORT_SYMBOL(drm_connector_update_edid_property);
@@ -1940,7 +2181,6 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
int encoders_count = 0;
int ret = 0;
int copied = 0;
- int i;
struct drm_mode_modeinfo u_mode;
struct drm_mode_modeinfo __user *mode_ptr;
uint32_t __user *encoder_ptr;
@@ -1955,14 +2195,13 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
if (!connector)
return -ENOENT;
- drm_connector_for_each_possible_encoder(connector, encoder, i)
- encoders_count++;
+ encoders_count = hweight32(connector->possible_encoders);
if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
copied = 0;
encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);
- drm_connector_for_each_possible_encoder(connector, encoder, i) {
+ drm_connector_for_each_possible_encoder(connector, encoder) {
if (put_user(encoder->base.id, encoder_ptr + copied)) {
ret = -EFAULT;
goto out;