diff options
Diffstat (limited to 'drivers/gpu/drm/drm_connector.c')
| -rw-r--r-- | drivers/gpu/drm/drm_connector.c | 122 | 
1 files changed, 115 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index e6a21e69059c..b3cde897cd80 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -205,9 +205,14 @@ int drm_connector_init(struct drm_device *dev,  	connector->dev = dev;  	connector->funcs = funcs; -	ret = ida_simple_get(&config->connector_ida, 0, 0, GFP_KERNEL); -	if (ret < 0) +	/* connector index is used with 32bit bitmasks */ +	ret = ida_simple_get(&config->connector_ida, 0, 32, GFP_KERNEL); +	if (ret < 0) { +		DRM_DEBUG_KMS("Failed to allocate %s connector index: %d\n", +			      drm_connector_enum_list[connector_type].name, +			      ret);  		goto out_put; +	}  	connector->index = ret;  	ret = 0; @@ -756,6 +761,13 @@ 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" }, +}; +DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list) +  /**   * DOC: standard connector properties   * @@ -817,14 +829,50 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,   * 	should update this value using drm_mode_connector_set_tile_property().   * 	Userspace cannot change this property.   * link-status: - *      Connector link-status property to indicate the status of link. The default - *      value of link-status is "GOOD". If something fails during or after modeset, - *      the kernel driver may set this to "BAD" and issue a hotplug uevent. Drivers - *      should update this value using drm_mode_connector_set_link_status_property(). + *      Connector link-status property to indicate the status of link. The + *      default value of link-status is "GOOD". If something fails during or + *      after modeset, the kernel driver may set this to "BAD" and issue a + *      hotplug uevent. Drivers should update this value using + *      drm_mode_connector_set_link_status_property().   * non_desktop:   * 	Indicates the output should be ignored for purposes of displaying a   * 	standard desktop environment or console. This is most likely because   * 	the output device is not rectilinear. + * Content Protection: + *	This property is used by userspace to request the kernel protect future + *	content communicated over the link. When requested, kernel will apply + *	the appropriate means of protection (most often HDCP), and use the + *	property to tell userspace the protection is active. + * + *	Drivers can set this up by calling + *	drm_connector_attach_content_protection_property() on initialization. + * + *	The value of this property can be one of the following: + * + *	DRM_MODE_CONTENT_PROTECTION_UNDESIRED = 0 + *		The link is not protected, content is transmitted in the clear. + *	DRM_MODE_CONTENT_PROTECTION_DESIRED = 1 + *		Userspace has requested content protection, but the link is not + *		currently protected. When in this state, kernel should enable + *		Content Protection as soon as possible. + *	DRM_MODE_CONTENT_PROTECTION_ENABLED = 2 + *		Userspace has requested content protection, and the link is + *		protected. Only the driver can set the property to this value. + *		If userspace attempts to set to ENABLED, kernel will return + *		-EINVAL. + * + *	A few guidelines: + * + *	- DESIRED state should be preserved until userspace de-asserts it by + *	  setting the property to UNDESIRED. This means ENABLED should only + *	  transition to UNDESIRED when the user explicitly requests it. + *	- 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).   *   * Connectors also have one standardized atomic property:   * @@ -841,7 +889,31 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,   *	INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel   *	coordinates, so if userspace rotates the picture to adjust for   *	the orientation it must also apply the same transformation to the - *	touchscreen input coordinates. + *	touchscreen input coordinates. This property is initialized by calling + *	drm_connector_init_panel_orientation_property(). + * + * scaling mode: + *	This property defines how a non-native mode is upscaled to the native + *	mode of an LCD panel: + * + *	None: + *		No upscaling happens, scaling is left to the panel. Not all + *		drivers expose this mode. + *	Full: + *		The output is upscaled to the full resolution of the panel, + *		ignoring the aspect ratio. + *	Center: + *		No upscaling happens, the output is centered within the native + *		resolution the panel. + *	Full aspect: + *		The output is upscaled to maximize either the width or height + *		while retaining the aspect ratio. + * + *	This property should be set up by calling + *	drm_connector_attach_scaling_mode_property(). Note that drivers + *	can also expose this property to external outputs, in which case they + *	must support "None", which should be the default (since external screens + *	have a built-in scaler).   */  int drm_connector_create_standard_properties(struct drm_device *dev) @@ -1126,6 +1198,42 @@ 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 + * + * @connector: connector to attach CP property on. + * + * 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. + * + * The content protection will be set to &drm_connector_state.content_protection + * + * Returns: + * Zero on success, negative errno on failure. + */ +int drm_connector_attach_content_protection_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; + +	drm_object_attach_property(&connector->base, prop, +				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED); + +	connector->content_protection_property = prop; + +	return 0; +} +EXPORT_SYMBOL(drm_connector_attach_content_protection_property); + +/**   * drm_mode_create_aspect_ratio_property - create aspect ratio property   * @dev: DRM device   *  |