brintos

brintos / linux-shallow public Read only

0
0
Text · 113.5 KiB · fc35f47 Raw
3453 lines · c
1/*2 * Copyright (c) 2016 Intel Corporation3 *4 * Permission to use, copy, modify, distribute, and sell this software and its5 * documentation for any purpose is hereby granted without fee, provided that6 * the above copyright notice appear in all copies and that both that copyright7 * notice and this permission notice appear in supporting documentation, and8 * that the name of the copyright holders not be used in advertising or9 * publicity pertaining to distribution of the software without specific,10 * written prior permission.  The copyright holders make no representations11 * about the suitability of this software for any purpose.  It is provided "as12 * is" without express or implied warranty.13 *14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE20 * OF THIS SOFTWARE.21 */22 23#include <drm/drm_auth.h>24#include <drm/drm_connector.h>25#include <drm/drm_drv.h>26#include <drm/drm_edid.h>27#include <drm/drm_encoder.h>28#include <drm/drm_file.h>29#include <drm/drm_managed.h>30#include <drm/drm_panel.h>31#include <drm/drm_print.h>32#include <drm/drm_privacy_screen_consumer.h>33#include <drm/drm_sysfs.h>34#include <drm/drm_utils.h>35 36#include <linux/property.h>37#include <linux/uaccess.h>38 39#include <video/cmdline.h>40 41#include "drm_crtc_internal.h"42#include "drm_internal.h"43 44/**45 * DOC: overview46 *47 * In DRM connectors are the general abstraction for display sinks, and include48 * also fixed panels or anything else that can display pixels in some form. As49 * opposed to all other KMS objects representing hardware (like CRTC, encoder or50 * plane abstractions) connectors can be hotplugged and unplugged at runtime.51 * Hence they are reference-counted using drm_connector_get() and52 * drm_connector_put().53 *54 * KMS driver must create, initialize, register and attach at a &struct55 * drm_connector for each such sink. The instance is created as other KMS56 * objects and initialized by setting the following fields. The connector is57 * initialized with a call to drm_connector_init() with a pointer to the58 * &struct drm_connector_funcs and a connector type, and then exposed to59 * userspace with a call to drm_connector_register().60 *61 * Connectors must be attached to an encoder to be used. For devices that map62 * connectors to encoders 1:1, the connector should be attached at63 * initialization time with a call to drm_connector_attach_encoder(). The64 * driver must also set the &drm_connector.encoder field to point to the65 * attached encoder.66 *67 * For connectors which are not fixed (like built-in panels) the driver needs to68 * support hotplug notifications. The simplest way to do that is by using the69 * probe helpers, see drm_kms_helper_poll_init() for connectors which don't have70 * hardware support for hotplug interrupts. Connectors with hardware hotplug71 * support can instead use e.g. drm_helper_hpd_irq_event().72 */73 74/*75 * Global connector list for drm_connector_find_by_fwnode().76 * Note drm_connector_[un]register() first take connector->lock and then77 * take the connector_list_lock.78 */79static DEFINE_MUTEX(connector_list_lock);80static LIST_HEAD(connector_list);81 82struct drm_conn_prop_enum_list {83	int type;84	const char *name;85	struct ida ida;86};87 88/*89 * Connector and encoder types.90 */91static struct drm_conn_prop_enum_list drm_connector_enum_list[] = {92	{ DRM_MODE_CONNECTOR_Unknown, "Unknown" },93	{ DRM_MODE_CONNECTOR_VGA, "VGA" },94	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },95	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },96	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },97	{ DRM_MODE_CONNECTOR_Composite, "Composite" },98	{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },99	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },100	{ DRM_MODE_CONNECTOR_Component, "Component" },101	{ DRM_MODE_CONNECTOR_9PinDIN, "DIN" },102	{ DRM_MODE_CONNECTOR_DisplayPort, "DP" },103	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },104	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },105	{ DRM_MODE_CONNECTOR_TV, "TV" },106	{ DRM_MODE_CONNECTOR_eDP, "eDP" },107	{ DRM_MODE_CONNECTOR_VIRTUAL, "Virtual" },108	{ DRM_MODE_CONNECTOR_DSI, "DSI" },109	{ DRM_MODE_CONNECTOR_DPI, "DPI" },110	{ DRM_MODE_CONNECTOR_WRITEBACK, "Writeback" },111	{ DRM_MODE_CONNECTOR_SPI, "SPI" },112	{ DRM_MODE_CONNECTOR_USB, "USB" },113};114 115void drm_connector_ida_init(void)116{117	int i;118 119	for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)120		ida_init(&drm_connector_enum_list[i].ida);121}122 123void drm_connector_ida_destroy(void)124{125	int i;126 127	for (i = 0; i < ARRAY_SIZE(drm_connector_enum_list); i++)128		ida_destroy(&drm_connector_enum_list[i].ida);129}130 131/**132 * drm_get_connector_type_name - return a string for connector type133 * @type: The connector type (DRM_MODE_CONNECTOR_*)134 *135 * Returns: the name of the connector type, or NULL if the type is not valid.136 */137const char *drm_get_connector_type_name(unsigned int type)138{139	if (type < ARRAY_SIZE(drm_connector_enum_list))140		return drm_connector_enum_list[type].name;141 142	return NULL;143}144EXPORT_SYMBOL(drm_get_connector_type_name);145 146/**147 * drm_connector_get_cmdline_mode - reads the user's cmdline mode148 * @connector: connector to query149 *150 * The kernel supports per-connector configuration of its consoles through151 * use of the video= parameter. This function parses that option and152 * extracts the user's specified mode (or enable/disable status) for a153 * particular connector. This is typically only used during the early fbdev154 * setup.155 */156static void drm_connector_get_cmdline_mode(struct drm_connector *connector)157{158	struct drm_cmdline_mode *mode = &connector->cmdline_mode;159	const char *option;160 161	option = video_get_options(connector->name);162	if (!option)163		return;164 165	if (!drm_mode_parse_command_line_for_connector(option,166						       connector,167						       mode))168		return;169 170	if (mode->force) {171		DRM_INFO("forcing %s connector %s\n", connector->name,172			 drm_get_connector_force_name(mode->force));173		connector->force = mode->force;174	}175 176	if (mode->panel_orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) {177		DRM_INFO("cmdline forces connector %s panel_orientation to %d\n",178			 connector->name, mode->panel_orientation);179		drm_connector_set_panel_orientation(connector,180						    mode->panel_orientation);181	}182 183	DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n",184		      connector->name, mode->name,185		      mode->xres, mode->yres,186		      mode->refresh_specified ? mode->refresh : 60,187		      mode->rb ? " reduced blanking" : "",188		      mode->margins ? " with margins" : "",189		      mode->interlace ?  " interlaced" : "");190}191 192static void drm_connector_free(struct kref *kref)193{194	struct drm_connector *connector =195		container_of(kref, struct drm_connector, base.refcount);196	struct drm_device *dev = connector->dev;197 198	drm_mode_object_unregister(dev, &connector->base);199	connector->funcs->destroy(connector);200}201 202void drm_connector_free_work_fn(struct work_struct *work)203{204	struct drm_connector *connector, *n;205	struct drm_device *dev =206		container_of(work, struct drm_device, mode_config.connector_free_work);207	struct drm_mode_config *config = &dev->mode_config;208	unsigned long flags;209	struct llist_node *freed;210 211	spin_lock_irqsave(&config->connector_list_lock, flags);212	freed = llist_del_all(&config->connector_free_list);213	spin_unlock_irqrestore(&config->connector_list_lock, flags);214 215	llist_for_each_entry_safe(connector, n, freed, free_node) {216		drm_mode_object_unregister(dev, &connector->base);217		connector->funcs->destroy(connector);218	}219}220 221static int __drm_connector_init(struct drm_device *dev,222				struct drm_connector *connector,223				const struct drm_connector_funcs *funcs,224				int connector_type,225				struct i2c_adapter *ddc)226{227	struct drm_mode_config *config = &dev->mode_config;228	int ret;229	struct ida *connector_ida =230		&drm_connector_enum_list[connector_type].ida;231 232	WARN_ON(drm_drv_uses_atomic_modeset(dev) &&233		(!funcs->atomic_destroy_state ||234		 !funcs->atomic_duplicate_state));235 236	ret = __drm_mode_object_add(dev, &connector->base,237				    DRM_MODE_OBJECT_CONNECTOR,238				    false, drm_connector_free);239	if (ret)240		return ret;241 242	connector->base.properties = &connector->properties;243	connector->dev = dev;244	connector->funcs = funcs;245 246	/* connector index is used with 32bit bitmasks */247	ret = ida_alloc_max(&config->connector_ida, 31, GFP_KERNEL);248	if (ret < 0) {249		DRM_DEBUG_KMS("Failed to allocate %s connector index: %d\n",250			      drm_connector_enum_list[connector_type].name,251			      ret);252		goto out_put;253	}254	connector->index = ret;255	ret = 0;256 257	connector->connector_type = connector_type;258	connector->connector_type_id =259		ida_alloc_min(connector_ida, 1, GFP_KERNEL);260	if (connector->connector_type_id < 0) {261		ret = connector->connector_type_id;262		goto out_put_id;263	}264	connector->name =265		kasprintf(GFP_KERNEL, "%s-%d",266			  drm_connector_enum_list[connector_type].name,267			  connector->connector_type_id);268	if (!connector->name) {269		ret = -ENOMEM;270		goto out_put_type_id;271	}272 273	/* provide ddc symlink in sysfs */274	connector->ddc = ddc;275 276	INIT_LIST_HEAD(&connector->global_connector_list_entry);277	INIT_LIST_HEAD(&connector->probed_modes);278	INIT_LIST_HEAD(&connector->modes);279	mutex_init(&connector->mutex);280	mutex_init(&connector->edid_override_mutex);281	mutex_init(&connector->hdmi.infoframes.lock);282	connector->edid_blob_ptr = NULL;283	connector->epoch_counter = 0;284	connector->tile_blob_ptr = NULL;285	connector->status = connector_status_unknown;286	connector->display_info.panel_orientation =287		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;288 289	drm_connector_get_cmdline_mode(connector);290 291	/* We should add connectors at the end to avoid upsetting the connector292	 * index too much.293	 */294	spin_lock_irq(&config->connector_list_lock);295	list_add_tail(&connector->head, &config->connector_list);296	config->num_connector++;297	spin_unlock_irq(&config->connector_list_lock);298 299	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL &&300	    connector_type != DRM_MODE_CONNECTOR_WRITEBACK)301		drm_connector_attach_edid_property(connector);302 303	drm_object_attach_property(&connector->base,304				      config->dpms_property, 0);305 306	drm_object_attach_property(&connector->base,307				   config->link_status_property,308				   0);309 310	drm_object_attach_property(&connector->base,311				   config->non_desktop_property,312				   0);313	drm_object_attach_property(&connector->base,314				   config->tile_property,315				   0);316 317	if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {318		drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);319	}320 321	connector->debugfs_entry = NULL;322out_put_type_id:323	if (ret)324		ida_free(connector_ida, connector->connector_type_id);325out_put_id:326	if (ret)327		ida_free(&config->connector_ida, connector->index);328out_put:329	if (ret)330		drm_mode_object_unregister(dev, &connector->base);331 332	return ret;333}334 335/**336 * drm_connector_init - Init a preallocated connector337 * @dev: DRM device338 * @connector: the connector to init339 * @funcs: callbacks for this connector340 * @connector_type: user visible type of the connector341 *342 * Initialises a preallocated connector. Connectors should be343 * subclassed as part of driver connector objects.344 *345 * At driver unload time the driver's &drm_connector_funcs.destroy hook346 * should call drm_connector_cleanup() and free the connector structure.347 * The connector structure should not be allocated with devm_kzalloc().348 *349 * Note: consider using drmm_connector_init() instead of350 * drm_connector_init() to let the DRM managed resource infrastructure351 * take care of cleanup and deallocation.352 *353 * Returns:354 * Zero on success, error code on failure.355 */356int drm_connector_init(struct drm_device *dev,357		       struct drm_connector *connector,358		       const struct drm_connector_funcs *funcs,359		       int connector_type)360{361	if (drm_WARN_ON(dev, !(funcs && funcs->destroy)))362		return -EINVAL;363 364	return __drm_connector_init(dev, connector, funcs, connector_type, NULL);365}366EXPORT_SYMBOL(drm_connector_init);367 368/**369 * drm_connector_init_with_ddc - Init a preallocated connector370 * @dev: DRM device371 * @connector: the connector to init372 * @funcs: callbacks for this connector373 * @connector_type: user visible type of the connector374 * @ddc: pointer to the associated ddc adapter375 *376 * Initialises a preallocated connector. Connectors should be377 * subclassed as part of driver connector objects.378 *379 * At driver unload time the driver's &drm_connector_funcs.destroy hook380 * should call drm_connector_cleanup() and free the connector structure.381 * The connector structure should not be allocated with devm_kzalloc().382 *383 * Ensures that the ddc field of the connector is correctly set.384 *385 * Note: consider using drmm_connector_init() instead of386 * drm_connector_init_with_ddc() to let the DRM managed resource387 * infrastructure take care of cleanup and deallocation.388 *389 * Returns:390 * Zero on success, error code on failure.391 */392int drm_connector_init_with_ddc(struct drm_device *dev,393				struct drm_connector *connector,394				const struct drm_connector_funcs *funcs,395				int connector_type,396				struct i2c_adapter *ddc)397{398	if (drm_WARN_ON(dev, !(funcs && funcs->destroy)))399		return -EINVAL;400 401	return __drm_connector_init(dev, connector, funcs, connector_type, ddc);402}403EXPORT_SYMBOL(drm_connector_init_with_ddc);404 405static void drm_connector_cleanup_action(struct drm_device *dev,406					 void *ptr)407{408	struct drm_connector *connector = ptr;409 410	drm_connector_cleanup(connector);411}412 413/**414 * drmm_connector_init - Init a preallocated connector415 * @dev: DRM device416 * @connector: the connector to init417 * @funcs: callbacks for this connector418 * @connector_type: user visible type of the connector419 * @ddc: optional pointer to the associated ddc adapter420 *421 * Initialises a preallocated connector. Connectors should be422 * subclassed as part of driver connector objects.423 *424 * Cleanup is automatically handled with a call to425 * drm_connector_cleanup() in a DRM-managed action.426 *427 * The connector structure should be allocated with drmm_kzalloc().428 *429 * The @drm_connector_funcs.destroy hook must be NULL.430 *431 * Returns:432 * Zero on success, error code on failure.433 */434int drmm_connector_init(struct drm_device *dev,435			struct drm_connector *connector,436			const struct drm_connector_funcs *funcs,437			int connector_type,438			struct i2c_adapter *ddc)439{440	int ret;441 442	if (drm_WARN_ON(dev, funcs && funcs->destroy))443		return -EINVAL;444 445	ret = __drm_connector_init(dev, connector, funcs, connector_type, ddc);446	if (ret)447		return ret;448 449	ret = drmm_add_action_or_reset(dev, drm_connector_cleanup_action,450				       connector);451	if (ret)452		return ret;453 454	return 0;455}456EXPORT_SYMBOL(drmm_connector_init);457 458/**459 * drmm_connector_hdmi_init - Init a preallocated HDMI connector460 * @dev: DRM device461 * @connector: A pointer to the HDMI connector to init462 * @vendor: HDMI Controller Vendor name463 * @product: HDMI Controller Product name464 * @funcs: callbacks for this connector465 * @hdmi_funcs: HDMI-related callbacks for this connector466 * @connector_type: user visible type of the connector467 * @ddc: optional pointer to the associated ddc adapter468 * @supported_formats: Bitmask of @hdmi_colorspace listing supported output formats469 * @max_bpc: Maximum bits per char the HDMI connector supports470 *471 * Initialises a preallocated HDMI connector. Connectors can be472 * subclassed as part of driver connector objects.473 *474 * Cleanup is automatically handled with a call to475 * drm_connector_cleanup() in a DRM-managed action.476 *477 * The connector structure should be allocated with drmm_kzalloc().478 *479 * The @drm_connector_funcs.destroy hook must be NULL.480 *481 * Returns:482 * Zero on success, error code on failure.483 */484int drmm_connector_hdmi_init(struct drm_device *dev,485			     struct drm_connector *connector,486			     const char *vendor, const char *product,487			     const struct drm_connector_funcs *funcs,488			     const struct drm_connector_hdmi_funcs *hdmi_funcs,489			     int connector_type,490			     struct i2c_adapter *ddc,491			     unsigned long supported_formats,492			     unsigned int max_bpc)493{494	int ret;495 496	if (!vendor || !product)497		return -EINVAL;498 499	if ((strlen(vendor) > DRM_CONNECTOR_HDMI_VENDOR_LEN) ||500	    (strlen(product) > DRM_CONNECTOR_HDMI_PRODUCT_LEN))501		return -EINVAL;502 503	if (!(connector_type == DRM_MODE_CONNECTOR_HDMIA ||504	      connector_type == DRM_MODE_CONNECTOR_HDMIB))505		return -EINVAL;506 507	if (!supported_formats || !(supported_formats & BIT(HDMI_COLORSPACE_RGB)))508		return -EINVAL;509 510	if (!(max_bpc == 8 || max_bpc == 10 || max_bpc == 12))511		return -EINVAL;512 513	ret = drmm_connector_init(dev, connector, funcs, connector_type, ddc);514	if (ret)515		return ret;516 517	connector->hdmi.supported_formats = supported_formats;518	strtomem_pad(connector->hdmi.vendor, vendor, 0);519	strtomem_pad(connector->hdmi.product, product, 0);520 521	/*522	 * drm_connector_attach_max_bpc_property() requires the523	 * connector to have a state.524	 */525	if (connector->funcs->reset)526		connector->funcs->reset(connector);527 528	drm_connector_attach_max_bpc_property(connector, 8, max_bpc);529	connector->max_bpc = max_bpc;530 531	if (max_bpc > 8)532		drm_connector_attach_hdr_output_metadata_property(connector);533 534	connector->hdmi.funcs = hdmi_funcs;535 536	return 0;537}538EXPORT_SYMBOL(drmm_connector_hdmi_init);539 540/**541 * drm_connector_attach_edid_property - attach edid property.542 * @connector: the connector543 *544 * Some connector types like DRM_MODE_CONNECTOR_VIRTUAL do not get a545 * edid property attached by default.  This function can be used to546 * explicitly enable the edid property in these cases.547 */548void drm_connector_attach_edid_property(struct drm_connector *connector)549{550	struct drm_mode_config *config = &connector->dev->mode_config;551 552	drm_object_attach_property(&connector->base,553				   config->edid_property,554				   0);555}556EXPORT_SYMBOL(drm_connector_attach_edid_property);557 558/**559 * drm_connector_attach_encoder - attach a connector to an encoder560 * @connector: connector to attach561 * @encoder: encoder to attach @connector to562 *563 * This function links up a connector to an encoder. Note that the routing564 * restrictions between encoders and crtcs are exposed to userspace through the565 * possible_clones and possible_crtcs bitmasks.566 *567 * Returns:568 * Zero on success, negative errno on failure.569 */570int drm_connector_attach_encoder(struct drm_connector *connector,571				 struct drm_encoder *encoder)572{573	/*574	 * In the past, drivers have attempted to model the static association575	 * of connector to encoder in simple connector/encoder devices using a576	 * direct assignment of connector->encoder = encoder. This connection577	 * is a logical one and the responsibility of the core, so drivers are578	 * expected not to mess with this.579	 *580	 * Note that the error return should've been enough here, but a large581	 * majority of drivers ignores the return value, so add in a big WARN582	 * to get people's attention.583	 */584	if (WARN_ON(connector->encoder))585		return -EINVAL;586 587	connector->possible_encoders |= drm_encoder_mask(encoder);588 589	return 0;590}591EXPORT_SYMBOL(drm_connector_attach_encoder);592 593/**594 * drm_connector_has_possible_encoder - check if the connector and encoder are595 * associated with each other596 * @connector: the connector597 * @encoder: the encoder598 *599 * Returns:600 * True if @encoder is one of the possible encoders for @connector.601 */602bool drm_connector_has_possible_encoder(struct drm_connector *connector,603					struct drm_encoder *encoder)604{605	return connector->possible_encoders & drm_encoder_mask(encoder);606}607EXPORT_SYMBOL(drm_connector_has_possible_encoder);608 609static void drm_mode_remove(struct drm_connector *connector,610			    struct drm_display_mode *mode)611{612	list_del(&mode->head);613	drm_mode_destroy(connector->dev, mode);614}615 616/**617 * drm_connector_cleanup - cleans up an initialised connector618 * @connector: connector to cleanup619 *620 * Cleans up the connector but doesn't free the object.621 */622void drm_connector_cleanup(struct drm_connector *connector)623{624	struct drm_device *dev = connector->dev;625	struct drm_display_mode *mode, *t;626 627	/* The connector should have been removed from userspace long before628	 * it is finally destroyed.629	 */630	if (WARN_ON(connector->registration_state ==631		    DRM_CONNECTOR_REGISTERED))632		drm_connector_unregister(connector);633 634	if (connector->privacy_screen) {635		drm_privacy_screen_put(connector->privacy_screen);636		connector->privacy_screen = NULL;637	}638 639	if (connector->tile_group) {640		drm_mode_put_tile_group(dev, connector->tile_group);641		connector->tile_group = NULL;642	}643 644	list_for_each_entry_safe(mode, t, &connector->probed_modes, head)645		drm_mode_remove(connector, mode);646 647	list_for_each_entry_safe(mode, t, &connector->modes, head)648		drm_mode_remove(connector, mode);649 650	ida_free(&drm_connector_enum_list[connector->connector_type].ida,651			  connector->connector_type_id);652 653	ida_free(&dev->mode_config.connector_ida, connector->index);654 655	kfree(connector->display_info.bus_formats);656	kfree(connector->display_info.vics);657	drm_mode_object_unregister(dev, &connector->base);658	kfree(connector->name);659	connector->name = NULL;660	fwnode_handle_put(connector->fwnode);661	connector->fwnode = NULL;662	spin_lock_irq(&dev->mode_config.connector_list_lock);663	list_del(&connector->head);664	dev->mode_config.num_connector--;665	spin_unlock_irq(&dev->mode_config.connector_list_lock);666 667	WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);668	if (connector->state && connector->funcs->atomic_destroy_state)669		connector->funcs->atomic_destroy_state(connector,670						       connector->state);671 672	mutex_destroy(&connector->hdmi.infoframes.lock);673	mutex_destroy(&connector->mutex);674 675	memset(connector, 0, sizeof(*connector));676 677	if (dev->registered)678		drm_sysfs_hotplug_event(dev);679}680EXPORT_SYMBOL(drm_connector_cleanup);681 682/**683 * drm_connector_register - register a connector684 * @connector: the connector to register685 *686 * Register userspace interfaces for a connector. Only call this for connectors687 * which can be hotplugged after drm_dev_register() has been called already,688 * e.g. DP MST connectors. All other connectors will be registered automatically689 * when calling drm_dev_register().690 *691 * When the connector is no longer available, callers must call692 * drm_connector_unregister().693 *694 * Returns:695 * Zero on success, error code on failure.696 */697int drm_connector_register(struct drm_connector *connector)698{699	int ret = 0;700 701	if (!connector->dev->registered)702		return 0;703 704	mutex_lock(&connector->mutex);705	if (connector->registration_state != DRM_CONNECTOR_INITIALIZING)706		goto unlock;707 708	ret = drm_sysfs_connector_add(connector);709	if (ret)710		goto unlock;711 712	drm_debugfs_connector_add(connector);713 714	if (connector->funcs->late_register) {715		ret = connector->funcs->late_register(connector);716		if (ret)717			goto err_debugfs;718	}719 720	ret = drm_sysfs_connector_add_late(connector);721	if (ret)722		goto err_late_register;723 724	drm_mode_object_register(connector->dev, &connector->base);725 726	connector->registration_state = DRM_CONNECTOR_REGISTERED;727 728	/* Let userspace know we have a new connector */729	drm_sysfs_connector_hotplug_event(connector);730 731	if (connector->privacy_screen)732		drm_privacy_screen_register_notifier(connector->privacy_screen,733					   &connector->privacy_screen_notifier);734 735	mutex_lock(&connector_list_lock);736	list_add_tail(&connector->global_connector_list_entry, &connector_list);737	mutex_unlock(&connector_list_lock);738	goto unlock;739 740err_late_register:741	if (connector->funcs->early_unregister)742		connector->funcs->early_unregister(connector);743err_debugfs:744	drm_debugfs_connector_remove(connector);745	drm_sysfs_connector_remove(connector);746unlock:747	mutex_unlock(&connector->mutex);748	return ret;749}750EXPORT_SYMBOL(drm_connector_register);751 752/**753 * drm_connector_unregister - unregister a connector754 * @connector: the connector to unregister755 *756 * Unregister userspace interfaces for a connector. Only call this for757 * connectors which have been registered explicitly by calling758 * drm_connector_register().759 */760void drm_connector_unregister(struct drm_connector *connector)761{762	mutex_lock(&connector->mutex);763	if (connector->registration_state != DRM_CONNECTOR_REGISTERED) {764		mutex_unlock(&connector->mutex);765		return;766	}767 768	mutex_lock(&connector_list_lock);769	list_del_init(&connector->global_connector_list_entry);770	mutex_unlock(&connector_list_lock);771 772	if (connector->privacy_screen)773		drm_privacy_screen_unregister_notifier(774					connector->privacy_screen,775					&connector->privacy_screen_notifier);776 777	drm_sysfs_connector_remove_early(connector);778 779	if (connector->funcs->early_unregister)780		connector->funcs->early_unregister(connector);781 782	drm_debugfs_connector_remove(connector);783	drm_sysfs_connector_remove(connector);784 785	connector->registration_state = DRM_CONNECTOR_UNREGISTERED;786	mutex_unlock(&connector->mutex);787}788EXPORT_SYMBOL(drm_connector_unregister);789 790void drm_connector_unregister_all(struct drm_device *dev)791{792	struct drm_connector *connector;793	struct drm_connector_list_iter conn_iter;794 795	drm_connector_list_iter_begin(dev, &conn_iter);796	drm_for_each_connector_iter(connector, &conn_iter)797		drm_connector_unregister(connector);798	drm_connector_list_iter_end(&conn_iter);799}800 801int drm_connector_register_all(struct drm_device *dev)802{803	struct drm_connector *connector;804	struct drm_connector_list_iter conn_iter;805	int ret = 0;806 807	drm_connector_list_iter_begin(dev, &conn_iter);808	drm_for_each_connector_iter(connector, &conn_iter) {809		ret = drm_connector_register(connector);810		if (ret)811			break;812	}813	drm_connector_list_iter_end(&conn_iter);814 815	if (ret)816		drm_connector_unregister_all(dev);817	return ret;818}819 820/**821 * drm_get_connector_status_name - return a string for connector status822 * @status: connector status to compute name of823 *824 * In contrast to the other drm_get_*_name functions this one here returns a825 * const pointer and hence is threadsafe.826 *827 * Returns: connector status string828 */829const char *drm_get_connector_status_name(enum drm_connector_status status)830{831	if (status == connector_status_connected)832		return "connected";833	else if (status == connector_status_disconnected)834		return "disconnected";835	else836		return "unknown";837}838EXPORT_SYMBOL(drm_get_connector_status_name);839 840/**841 * drm_get_connector_force_name - return a string for connector force842 * @force: connector force to get name of843 *844 * Returns: const pointer to name.845 */846const char *drm_get_connector_force_name(enum drm_connector_force force)847{848	switch (force) {849	case DRM_FORCE_UNSPECIFIED:850		return "unspecified";851	case DRM_FORCE_OFF:852		return "off";853	case DRM_FORCE_ON:854		return "on";855	case DRM_FORCE_ON_DIGITAL:856		return "digital";857	default:858		return "unknown";859	}860}861 862#ifdef CONFIG_LOCKDEP863static struct lockdep_map connector_list_iter_dep_map = {864	.name = "drm_connector_list_iter"865};866#endif867 868/**869 * drm_connector_list_iter_begin - initialize a connector_list iterator870 * @dev: DRM device871 * @iter: connector_list iterator872 *873 * Sets @iter up to walk the &drm_mode_config.connector_list of @dev. @iter874 * must always be cleaned up again by calling drm_connector_list_iter_end().875 * Iteration itself happens using drm_connector_list_iter_next() or876 * drm_for_each_connector_iter().877 */878void drm_connector_list_iter_begin(struct drm_device *dev,879				   struct drm_connector_list_iter *iter)880{881	iter->dev = dev;882	iter->conn = NULL;883	lock_acquire_shared_recursive(&connector_list_iter_dep_map, 0, 1, NULL, _RET_IP_);884}885EXPORT_SYMBOL(drm_connector_list_iter_begin);886 887/*888 * Extra-safe connector put function that works in any context. Should only be889 * used from the connector_iter functions, where we never really expect to890 * actually release the connector when dropping our final reference.891 */892static void893__drm_connector_put_safe(struct drm_connector *conn)894{895	struct drm_mode_config *config = &conn->dev->mode_config;896 897	lockdep_assert_held(&config->connector_list_lock);898 899	if (!refcount_dec_and_test(&conn->base.refcount.refcount))900		return;901 902	llist_add(&conn->free_node, &config->connector_free_list);903	schedule_work(&config->connector_free_work);904}905 906/**907 * drm_connector_list_iter_next - return next connector908 * @iter: connector_list iterator909 *910 * Returns: the next connector for @iter, or NULL when the list walk has911 * completed.912 */913struct drm_connector *914drm_connector_list_iter_next(struct drm_connector_list_iter *iter)915{916	struct drm_connector *old_conn = iter->conn;917	struct drm_mode_config *config = &iter->dev->mode_config;918	struct list_head *lhead;919	unsigned long flags;920 921	spin_lock_irqsave(&config->connector_list_lock, flags);922	lhead = old_conn ? &old_conn->head : &config->connector_list;923 924	do {925		if (lhead->next == &config->connector_list) {926			iter->conn = NULL;927			break;928		}929 930		lhead = lhead->next;931		iter->conn = list_entry(lhead, struct drm_connector, head);932 933		/* loop until it's not a zombie connector */934	} while (!kref_get_unless_zero(&iter->conn->base.refcount));935 936	if (old_conn)937		__drm_connector_put_safe(old_conn);938	spin_unlock_irqrestore(&config->connector_list_lock, flags);939 940	return iter->conn;941}942EXPORT_SYMBOL(drm_connector_list_iter_next);943 944/**945 * drm_connector_list_iter_end - tear down a connector_list iterator946 * @iter: connector_list iterator947 *948 * Tears down @iter and releases any resources (like &drm_connector references)949 * acquired while walking the list. This must always be called, both when the950 * iteration completes fully or when it was aborted without walking the entire951 * list.952 */953void drm_connector_list_iter_end(struct drm_connector_list_iter *iter)954{955	struct drm_mode_config *config = &iter->dev->mode_config;956	unsigned long flags;957 958	iter->dev = NULL;959	if (iter->conn) {960		spin_lock_irqsave(&config->connector_list_lock, flags);961		__drm_connector_put_safe(iter->conn);962		spin_unlock_irqrestore(&config->connector_list_lock, flags);963	}964	lock_release(&connector_list_iter_dep_map, _RET_IP_);965}966EXPORT_SYMBOL(drm_connector_list_iter_end);967 968static const struct drm_prop_enum_list drm_subpixel_enum_list[] = {969	{ SubPixelUnknown, "Unknown" },970	{ SubPixelHorizontalRGB, "Horizontal RGB" },971	{ SubPixelHorizontalBGR, "Horizontal BGR" },972	{ SubPixelVerticalRGB, "Vertical RGB" },973	{ SubPixelVerticalBGR, "Vertical BGR" },974	{ SubPixelNone, "None" },975};976 977/**978 * drm_get_subpixel_order_name - return a string for a given subpixel enum979 * @order: enum of subpixel_order980 *981 * Note you could abuse this and return something out of bounds, but that982 * would be a caller error.  No unscrubbed user data should make it here.983 *984 * Returns: string describing an enumerated subpixel property985 */986const char *drm_get_subpixel_order_name(enum subpixel_order order)987{988	return drm_subpixel_enum_list[order].name;989}990EXPORT_SYMBOL(drm_get_subpixel_order_name);991 992static const struct drm_prop_enum_list drm_dpms_enum_list[] = {993	{ DRM_MODE_DPMS_ON, "On" },994	{ DRM_MODE_DPMS_STANDBY, "Standby" },995	{ DRM_MODE_DPMS_SUSPEND, "Suspend" },996	{ DRM_MODE_DPMS_OFF, "Off" }997};998DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)999 1000static const struct drm_prop_enum_list drm_link_status_enum_list[] = {1001	{ DRM_MODE_LINK_STATUS_GOOD, "Good" },1002	{ DRM_MODE_LINK_STATUS_BAD, "Bad" },1003};1004 1005/**1006 * drm_display_info_set_bus_formats - set the supported bus formats1007 * @info: display info to store bus formats in1008 * @formats: array containing the supported bus formats1009 * @num_formats: the number of entries in the fmts array1010 *1011 * Store the supported bus formats in display info structure.1012 * See MEDIA_BUS_FMT_* definitions in include/uapi/linux/media-bus-format.h for1013 * a full list of available formats.1014 *1015 * Returns:1016 * 0 on success or a negative error code on failure.1017 */1018int drm_display_info_set_bus_formats(struct drm_display_info *info,1019				     const u32 *formats,1020				     unsigned int num_formats)1021{1022	u32 *fmts = NULL;1023 1024	if (!formats && num_formats)1025		return -EINVAL;1026 1027	if (formats && num_formats) {1028		fmts = kmemdup(formats, sizeof(*formats) * num_formats,1029			       GFP_KERNEL);1030		if (!fmts)1031			return -ENOMEM;1032	}1033 1034	kfree(info->bus_formats);1035	info->bus_formats = fmts;1036	info->num_bus_formats = num_formats;1037 1038	return 0;1039}1040EXPORT_SYMBOL(drm_display_info_set_bus_formats);1041 1042/* Optional connector properties. */1043static const struct drm_prop_enum_list drm_scaling_mode_enum_list[] = {1044	{ DRM_MODE_SCALE_NONE, "None" },1045	{ DRM_MODE_SCALE_FULLSCREEN, "Full" },1046	{ DRM_MODE_SCALE_CENTER, "Center" },1047	{ DRM_MODE_SCALE_ASPECT, "Full aspect" },1048};1049 1050static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {1051	{ DRM_MODE_PICTURE_ASPECT_NONE, "Automatic" },1052	{ DRM_MODE_PICTURE_ASPECT_4_3, "4:3" },1053	{ DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },1054};1055 1056static const struct drm_prop_enum_list drm_content_type_enum_list[] = {1057	{ DRM_MODE_CONTENT_TYPE_NO_DATA, "No Data" },1058	{ DRM_MODE_CONTENT_TYPE_GRAPHICS, "Graphics" },1059	{ DRM_MODE_CONTENT_TYPE_PHOTO, "Photo" },1060	{ DRM_MODE_CONTENT_TYPE_CINEMA, "Cinema" },1061	{ DRM_MODE_CONTENT_TYPE_GAME, "Game" },1062};1063 1064static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {1065	{ DRM_MODE_PANEL_ORIENTATION_NORMAL,	"Normal"	},1066	{ DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP,	"Upside Down"	},1067	{ DRM_MODE_PANEL_ORIENTATION_LEFT_UP,	"Left Side Up"	},1068	{ DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,	"Right Side Up"	},1069};1070 1071static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = {1072	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */1073	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */1074	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */1075};1076DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)1077 1078static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {1079	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I, TV-out and DP */1080	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */1081	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */1082};1083DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,1084		 drm_dvi_i_subconnector_enum_list)1085 1086static const struct drm_prop_enum_list drm_tv_mode_enum_list[] = {1087	{ DRM_MODE_TV_MODE_NTSC, "NTSC" },1088	{ DRM_MODE_TV_MODE_NTSC_443, "NTSC-443" },1089	{ DRM_MODE_TV_MODE_NTSC_J, "NTSC-J" },1090	{ DRM_MODE_TV_MODE_PAL, "PAL" },1091	{ DRM_MODE_TV_MODE_PAL_M, "PAL-M" },1092	{ DRM_MODE_TV_MODE_PAL_N, "PAL-N" },1093	{ DRM_MODE_TV_MODE_SECAM, "SECAM" },1094	{ DRM_MODE_TV_MODE_MONOCHROME, "Mono" },1095};1096DRM_ENUM_NAME_FN(drm_get_tv_mode_name, drm_tv_mode_enum_list)1097 1098/**1099 * drm_get_tv_mode_from_name - Translates a TV mode name into its enum value1100 * @name: TV Mode name we want to convert1101 * @len: Length of @name1102 *1103 * Translates @name into an enum drm_connector_tv_mode.1104 *1105 * Returns: the enum value on success, a negative errno otherwise.1106 */1107int drm_get_tv_mode_from_name(const char *name, size_t len)1108{1109	unsigned int i;1110 1111	for (i = 0; i < ARRAY_SIZE(drm_tv_mode_enum_list); i++) {1112		const struct drm_prop_enum_list *item = &drm_tv_mode_enum_list[i];1113 1114		if (strlen(item->name) == len && !strncmp(item->name, name, len))1115			return item->type;1116	}1117 1118	return -EINVAL;1119}1120EXPORT_SYMBOL(drm_get_tv_mode_from_name);1121 1122static const struct drm_prop_enum_list drm_tv_select_enum_list[] = {1123	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */1124	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */1125	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */1126	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */1127	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */1128};1129DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)1130 1131static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {1132	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I, TV-out and DP */1133	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */1134	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */1135	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */1136	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */1137};1138DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,1139		 drm_tv_subconnector_enum_list)1140 1141static const struct drm_prop_enum_list drm_dp_subconnector_enum_list[] = {1142	{ DRM_MODE_SUBCONNECTOR_Unknown,     "Unknown"   }, /* DVI-I, TV-out and DP */1143	{ DRM_MODE_SUBCONNECTOR_VGA,	     "VGA"       }, /* DP */1144	{ DRM_MODE_SUBCONNECTOR_DVID,	     "DVI-D"     }, /* DP */1145	{ DRM_MODE_SUBCONNECTOR_HDMIA,	     "HDMI"      }, /* DP */1146	{ DRM_MODE_SUBCONNECTOR_DisplayPort, "DP"        }, /* DP */1147	{ DRM_MODE_SUBCONNECTOR_Wireless,    "Wireless"  }, /* DP */1148	{ DRM_MODE_SUBCONNECTOR_Native,	     "Native"    }, /* DP */1149};1150 1151DRM_ENUM_NAME_FN(drm_get_dp_subconnector_name,1152		 drm_dp_subconnector_enum_list)1153 1154 1155static const char * const colorspace_names[] = {1156	/* For Default case, driver will set the colorspace */1157	[DRM_MODE_COLORIMETRY_DEFAULT] = "Default",1158	/* Standard Definition Colorimetry based on CEA 861 */1159	[DRM_MODE_COLORIMETRY_SMPTE_170M_YCC] = "SMPTE_170M_YCC",1160	[DRM_MODE_COLORIMETRY_BT709_YCC] = "BT709_YCC",1161	/* Standard Definition Colorimetry based on IEC 61966-2-4 */1162	[DRM_MODE_COLORIMETRY_XVYCC_601] = "XVYCC_601",1163	/* High Definition Colorimetry based on IEC 61966-2-4 */1164	[DRM_MODE_COLORIMETRY_XVYCC_709] = "XVYCC_709",1165	/* Colorimetry based on IEC 61966-2-1/Amendment 1 */1166	[DRM_MODE_COLORIMETRY_SYCC_601] = "SYCC_601",1167	/* Colorimetry based on IEC 61966-2-5 [33] */1168	[DRM_MODE_COLORIMETRY_OPYCC_601] = "opYCC_601",1169	/* Colorimetry based on IEC 61966-2-5 */1170	[DRM_MODE_COLORIMETRY_OPRGB] = "opRGB",1171	/* Colorimetry based on ITU-R BT.2020 */1172	[DRM_MODE_COLORIMETRY_BT2020_CYCC] = "BT2020_CYCC",1173	/* Colorimetry based on ITU-R BT.2020 */1174	[DRM_MODE_COLORIMETRY_BT2020_RGB] = "BT2020_RGB",1175	/* Colorimetry based on ITU-R BT.2020 */1176	[DRM_MODE_COLORIMETRY_BT2020_YCC] = "BT2020_YCC",1177	/* Added as part of Additional Colorimetry Extension in 861.G */1178	[DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65] = "DCI-P3_RGB_D65",1179	[DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER] = "DCI-P3_RGB_Theater",1180	[DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED] = "RGB_WIDE_FIXED",1181	/* Colorimetry based on scRGB (IEC 61966-2-2) */1182	[DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT] = "RGB_WIDE_FLOAT",1183	[DRM_MODE_COLORIMETRY_BT601_YCC] = "BT601_YCC",1184};1185 1186/**1187 * drm_get_colorspace_name - return a string for color encoding1188 * @colorspace: color space to compute name of1189 *1190 * In contrast to the other drm_get_*_name functions this one here returns a1191 * const pointer and hence is threadsafe.1192 */1193const char *drm_get_colorspace_name(enum drm_colorspace colorspace)1194{1195	if (colorspace < ARRAY_SIZE(colorspace_names) && colorspace_names[colorspace])1196		return colorspace_names[colorspace];1197	else1198		return "(null)";1199}1200 1201static const u32 hdmi_colorspaces =1202	BIT(DRM_MODE_COLORIMETRY_SMPTE_170M_YCC) |1203	BIT(DRM_MODE_COLORIMETRY_BT709_YCC) |1204	BIT(DRM_MODE_COLORIMETRY_XVYCC_601) |1205	BIT(DRM_MODE_COLORIMETRY_XVYCC_709) |1206	BIT(DRM_MODE_COLORIMETRY_SYCC_601) |1207	BIT(DRM_MODE_COLORIMETRY_OPYCC_601) |1208	BIT(DRM_MODE_COLORIMETRY_OPRGB) |1209	BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |1210	BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |1211	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC) |1212	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) |1213	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER);1214 1215/*1216 * As per DP 1.4a spec, 2.2.5.7.5 VSC SDP Payload for Pixel Encoding/Colorimetry1217 * Format Table 2-1201218 */1219static const u32 dp_colorspaces =1220	BIT(DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED) |1221	BIT(DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT) |1222	BIT(DRM_MODE_COLORIMETRY_OPRGB) |1223	BIT(DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65) |1224	BIT(DRM_MODE_COLORIMETRY_BT2020_RGB) |1225	BIT(DRM_MODE_COLORIMETRY_BT601_YCC) |1226	BIT(DRM_MODE_COLORIMETRY_BT709_YCC) |1227	BIT(DRM_MODE_COLORIMETRY_XVYCC_601) |1228	BIT(DRM_MODE_COLORIMETRY_XVYCC_709) |1229	BIT(DRM_MODE_COLORIMETRY_SYCC_601) |1230	BIT(DRM_MODE_COLORIMETRY_OPYCC_601) |1231	BIT(DRM_MODE_COLORIMETRY_BT2020_CYCC) |1232	BIT(DRM_MODE_COLORIMETRY_BT2020_YCC);1233 1234static const struct drm_prop_enum_list broadcast_rgb_names[] = {1235	{ DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic" },1236	{ DRM_HDMI_BROADCAST_RGB_FULL, "Full" },1237	{ DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235" },1238};1239 1240/*1241 * drm_hdmi_connector_get_broadcast_rgb_name - Return a string for HDMI connector RGB broadcast selection1242 * @broadcast_rgb: Broadcast RGB selection to compute name of1243 *1244 * Returns: the name of the Broadcast RGB selection, or NULL if the type1245 * is not valid.1246 */1247const char *1248drm_hdmi_connector_get_broadcast_rgb_name(enum drm_hdmi_broadcast_rgb broadcast_rgb)1249{1250	if (broadcast_rgb >= ARRAY_SIZE(broadcast_rgb_names))1251		return NULL;1252 1253	return broadcast_rgb_names[broadcast_rgb].name;1254}1255EXPORT_SYMBOL(drm_hdmi_connector_get_broadcast_rgb_name);1256 1257static const char * const output_format_str[] = {1258	[HDMI_COLORSPACE_RGB]		= "RGB",1259	[HDMI_COLORSPACE_YUV420]	= "YUV 4:2:0",1260	[HDMI_COLORSPACE_YUV422]	= "YUV 4:2:2",1261	[HDMI_COLORSPACE_YUV444]	= "YUV 4:4:4",1262};1263 1264/*1265 * drm_hdmi_connector_get_output_format_name() - Return a string for HDMI connector output format1266 * @fmt: Output format to compute name of1267 *1268 * Returns: the name of the output format, or NULL if the type is not1269 * valid.1270 */1271const char *1272drm_hdmi_connector_get_output_format_name(enum hdmi_colorspace fmt)1273{1274	if (fmt >= ARRAY_SIZE(output_format_str))1275		return NULL;1276 1277	return output_format_str[fmt];1278}1279EXPORT_SYMBOL(drm_hdmi_connector_get_output_format_name);1280 1281/**1282 * DOC: standard connector properties1283 *1284 * DRM connectors have a few standardized properties:1285 *1286 * EDID:1287 * 	Blob property which contains the current EDID read from the sink. This1288 * 	is useful to parse sink identification information like vendor, model1289 * 	and serial. Drivers should update this property by calling1290 * 	drm_connector_update_edid_property(), usually after having parsed1291 * 	the EDID using drm_add_edid_modes(). Userspace cannot change this1292 * 	property.1293 *1294 * 	User-space should not parse the EDID to obtain information exposed via1295 * 	other KMS properties (because the kernel might apply limits, quirks or1296 * 	fixups to the EDID). For instance, user-space should not try to parse1297 * 	mode lists from the EDID.1298 * DPMS:1299 * 	Legacy property for setting the power state of the connector. For atomic1300 * 	drivers this is only provided for backwards compatibility with existing1301 * 	drivers, it remaps to controlling the "ACTIVE" property on the CRTC the1302 * 	connector is linked to. Drivers should never set this property directly,1303 * 	it is handled by the DRM core by calling the &drm_connector_funcs.dpms1304 * 	callback. For atomic drivers the remapping to the "ACTIVE" property is1305 * 	implemented in the DRM core.1306 *1307 * 	Note that this property cannot be set through the MODE_ATOMIC ioctl,1308 * 	userspace must use "ACTIVE" on the CRTC instead.1309 *1310 * 	WARNING:1311 *1312 * 	For userspace also running on legacy drivers the "DPMS" semantics are a1313 * 	lot more complicated. First, userspace cannot rely on the "DPMS" value1314 * 	returned by the GETCONNECTOR actually reflecting reality, because many1315 * 	drivers fail to update it. For atomic drivers this is taken care of in1316 * 	drm_atomic_helper_update_legacy_modeset_state().1317 *1318 * 	The second issue is that the DPMS state is only well-defined when the1319 * 	connector is connected to a CRTC. In atomic the DRM core enforces that1320 * 	"ACTIVE" is off in such a case, no such checks exists for "DPMS".1321 *1322 * 	Finally, when enabling an output using the legacy SETCONFIG ioctl then1323 * 	"DPMS" is forced to ON. But see above, that might not be reflected in1324 * 	the software value on legacy drivers.1325 *1326 * 	Summarizing: Only set "DPMS" when the connector is known to be enabled,1327 * 	assume that a successful SETCONFIG call also sets "DPMS" to on, and1328 * 	never read back the value of "DPMS" because it can be incorrect.1329 * PATH:1330 * 	Connector path property to identify how this sink is physically1331 * 	connected. Used by DP MST. This should be set by calling1332 * 	drm_connector_set_path_property(), in the case of DP MST with the1333 * 	path property the MST manager created. Userspace cannot change this1334 * 	property.1335 *1336 * 	In the case of DP MST, the property has the format1337 * 	``mst:<parent>-<ports>`` where ``<parent>`` is the KMS object ID of the1338 * 	parent connector and ``<ports>`` is a hyphen-separated list of DP MST1339 * 	port numbers. Note, KMS object IDs are not guaranteed to be stable1340 * 	across reboots.1341 * TILE:1342 * 	Connector tile group property to indicate how a set of DRM connector1343 * 	compose together into one logical screen. This is used by both high-res1344 * 	external screens (often only using a single cable, but exposing multiple1345 * 	DP MST sinks), or high-res integrated panels (like dual-link DSI) which1346 * 	are not gen-locked. Note that for tiled panels which are genlocked, like1347 * 	dual-link LVDS or dual-link DSI, the driver should try to not expose the1348 * 	tiling and virtualise both &drm_crtc and &drm_plane if needed. Drivers1349 * 	should update this value using drm_connector_set_tile_property().1350 * 	Userspace cannot change this property.1351 * link-status:1352 *      Connector link-status property to indicate the status of link. The1353 *      default value of link-status is "GOOD". If something fails during or1354 *      after modeset, the kernel driver may set this to "BAD" and issue a1355 *      hotplug uevent. Drivers should update this value using1356 *      drm_connector_set_link_status_property().1357 *1358 *      When user-space receives the hotplug uevent and detects a "BAD"1359 *      link-status, the sink doesn't receive pixels anymore (e.g. the screen1360 *      becomes completely black). The list of available modes may have1361 *      changed. User-space is expected to pick a new mode if the current one1362 *      has disappeared and perform a new modeset with link-status set to1363 *      "GOOD" to re-enable the connector.1364 *1365 *      If multiple connectors share the same CRTC and one of them gets a "BAD"1366 *      link-status, the other are unaffected (ie. the sinks still continue to1367 *      receive pixels).1368 *1369 *      When user-space performs an atomic commit on a connector with a "BAD"1370 *      link-status without resetting the property to "GOOD", the sink may1371 *      still not receive pixels. When user-space performs an atomic commit1372 *      which resets the link-status property to "GOOD" without the1373 *      ALLOW_MODESET flag set, it might fail because a modeset is required.1374 *1375 *      User-space can only change link-status to "GOOD", changing it to "BAD"1376 *      is a no-op.1377 *1378 *      For backwards compatibility with non-atomic userspace the kernel1379 *      tries to automatically set the link-status back to "GOOD" in the1380 *      SETCRTC IOCTL. This might fail if the mode is no longer valid, similar1381 *      to how it might fail if a different screen has been connected in the1382 *      interim.1383 * non_desktop:1384 * 	Indicates the output should be ignored for purposes of displaying a1385 * 	standard desktop environment or console. This is most likely because1386 * 	the output device is not rectilinear.1387 * Content Protection:1388 *	This property is used by userspace to request the kernel protect future1389 *	content communicated over the link. When requested, kernel will apply1390 *	the appropriate means of protection (most often HDCP), and use the1391 *	property to tell userspace the protection is active.1392 *1393 *	Drivers can set this up by calling1394 *	drm_connector_attach_content_protection_property() on initialization.1395 *1396 *	The value of this property can be one of the following:1397 *1398 *	DRM_MODE_CONTENT_PROTECTION_UNDESIRED = 01399 *		The link is not protected, content is transmitted in the clear.1400 *	DRM_MODE_CONTENT_PROTECTION_DESIRED = 11401 *		Userspace has requested content protection, but the link is not1402 *		currently protected. When in this state, kernel should enable1403 *		Content Protection as soon as possible.1404 *	DRM_MODE_CONTENT_PROTECTION_ENABLED = 21405 *		Userspace has requested content protection, and the link is1406 *		protected. Only the driver can set the property to this value.1407 *		If userspace attempts to set to ENABLED, kernel will return1408 *		-EINVAL.1409 *1410 *	A few guidelines:1411 *1412 *	- DESIRED state should be preserved until userspace de-asserts it by1413 *	  setting the property to UNDESIRED. This means ENABLED should only1414 *	  transition to UNDESIRED when the user explicitly requests it.1415 *	- If the state is DESIRED, kernel should attempt to re-authenticate the1416 *	  link whenever possible. This includes across disable/enable, dpms,1417 *	  hotplug, downstream device changes, link status failures, etc..1418 *	- Kernel sends uevent with the connector id and property id through1419 *	  @drm_hdcp_update_content_protection, upon below kernel triggered1420 *	  scenarios:1421 *1422 *		- DESIRED -> ENABLED (authentication success)1423 *		- ENABLED -> DESIRED (termination of authentication)1424 *	- Please note no uevents for userspace triggered property state changes,1425 *	  which can't fail such as1426 *1427 *		- DESIRED/ENABLED -> UNDESIRED1428 *		- UNDESIRED -> DESIRED1429 *	- Userspace is responsible for polling the property or listen to uevents1430 *	  to determine when the value transitions from ENABLED to DESIRED.1431 *	  This signifies the link is no longer protected and userspace should1432 *	  take appropriate action (whatever that might be).1433 *1434 * HDCP Content Type:1435 *	This Enum property is used by the userspace to declare the content type1436 *	of the display stream, to kernel. Here display stream stands for any1437 *	display content that userspace intended to display through HDCP1438 *	encryption.1439 *1440 *	Content Type of a stream is decided by the owner of the stream, as1441 *	"HDCP Type0" or "HDCP Type1".1442 *1443 *	The value of the property can be one of the below:1444 *	  - "HDCP Type0": DRM_MODE_HDCP_CONTENT_TYPE0 = 01445 *	  - "HDCP Type1": DRM_MODE_HDCP_CONTENT_TYPE1 = 11446 *1447 *	When kernel starts the HDCP authentication (see "Content Protection"1448 *	for details), it uses the content type in "HDCP Content Type"1449 *	for performing the HDCP authentication with the display sink.1450 *1451 *	Please note in HDCP spec versions, a link can be authenticated with1452 *	HDCP 2.2 for Content Type 0/Content Type 1. Where as a link can be1453 *	authenticated with HDCP1.4 only for Content Type 0(though it is implicit1454 *	in nature. As there is no reference for Content Type in HDCP1.4).1455 *1456 *	HDCP2.2 authentication protocol itself takes the "Content Type" as a1457 *	parameter, which is a input for the DP HDCP2.2 encryption algo.1458 *1459 *	In case of Type 0 content protection request, kernel driver can choose1460 *	either of HDCP spec versions 1.4 and 2.2. When HDCP2.2 is used for1461 *	"HDCP Type 0", a HDCP 2.2 capable repeater in the downstream can send1462 *	that content to a HDCP 1.4 authenticated HDCP sink (Type0 link).1463 *	But if the content is classified as "HDCP Type 1", above mentioned1464 *	HDCP 2.2 repeater wont send the content to the HDCP sink as it can't1465 *	authenticate the HDCP1.4 capable sink for "HDCP Type 1".1466 *1467 *	Please note userspace can be ignorant of the HDCP versions used by the1468 *	kernel driver to achieve the "HDCP Content Type".1469 *1470 *	At current scenario, classifying a content as Type 1 ensures that the1471 *	content will be displayed only through the HDCP2.2 encrypted link.1472 *1473 *	Note that the HDCP Content Type property is introduced at HDCP 2.2, and1474 *	defaults to type 0. It is only exposed by drivers supporting HDCP 2.21475 *	(hence supporting Type 0 and Type 1). Based on how next versions of1476 *	HDCP specs are defined content Type could be used for higher versions1477 *	too.1478 *1479 *	If content type is changed when "Content Protection" is not UNDESIRED,1480 *	then kernel will disable the HDCP and re-enable with new type in the1481 *	same atomic commit. And when "Content Protection" is ENABLED, it means1482 *	that link is HDCP authenticated and encrypted, for the transmission of1483 *	the Type of stream mentioned at "HDCP Content Type".1484 *1485 * HDR_OUTPUT_METADATA:1486 *	Connector property to enable userspace to send HDR Metadata to1487 *	driver. This metadata is based on the composition and blending1488 *	policies decided by user, taking into account the hardware and1489 *	sink capabilities. The driver gets this metadata and creates a1490 *	Dynamic Range and Mastering Infoframe (DRM) in case of HDMI,1491 *	SDP packet (Non-audio INFOFRAME SDP v1.3) for DP. This is then1492 *	sent to sink. This notifies the sink of the upcoming frame's Color1493 *	Encoding and Luminance parameters.1494 *1495 *	Userspace first need to detect the HDR capabilities of sink by1496 *	reading and parsing the EDID. Details of HDR metadata for HDMI1497 *	are added in CTA 861.G spec. For DP , its defined in VESA DP1498 *	Standard v1.4. It needs to then get the metadata information1499 *	of the video/game/app content which are encoded in HDR (basically1500 *	using HDR transfer functions). With this information it needs to1501 *	decide on a blending policy and compose the relevant1502 *	layers/overlays into a common format. Once this blending is done,1503 *	userspace will be aware of the metadata of the composed frame to1504 *	be send to sink. It then uses this property to communicate this1505 *	metadata to driver which then make a Infoframe packet and sends1506 *	to sink based on the type of encoder connected.1507 *1508 *	Userspace will be responsible to do Tone mapping operation in case:1509 *		- Some layers are HDR and others are SDR1510 *		- HDR layers luminance is not same as sink1511 *1512 *	It will even need to do colorspace conversion and get all layers1513 *	to one common colorspace for blending. It can use either GL, Media1514 *	or display engine to get this done based on the capabilities of the1515 *	associated hardware.1516 *1517 *	Driver expects metadata to be put in &struct hdr_output_metadata1518 *	structure from userspace. This is received as blob and stored in1519 *	&drm_connector_state.hdr_output_metadata. It parses EDID and saves the1520 *	sink metadata in &struct hdr_sink_metadata, as1521 *	&drm_connector.hdr_sink_metadata.  Driver uses1522 *	drm_hdmi_infoframe_set_hdr_metadata() helper to set the HDR metadata,1523 *	hdmi_drm_infoframe_pack() to pack the infoframe as per spec, in case of1524 *	HDMI encoder.1525 *1526 * max bpc:1527 *	This range property is used by userspace to limit the bit depth. When1528 *	used the driver would limit the bpc in accordance with the valid range1529 *	supported by the hardware and sink. Drivers to use the function1530 *	drm_connector_attach_max_bpc_property() to create and attach the1531 *	property to the connector during initialization.1532 *1533 * Connectors also have one standardized atomic property:1534 *1535 * CRTC_ID:1536 * 	Mode object ID of the &drm_crtc this connector should be connected to.1537 *1538 * Connectors for LCD panels may also have one standardized property:1539 *1540 * panel orientation:1541 *	On some devices the LCD panel is mounted in the casing in such a way1542 *	that the up/top side of the panel does not match with the top side of1543 *	the device. Userspace can use this property to check for this.1544 *	Note that input coordinates from touchscreens (input devices with1545 *	INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel1546 *	coordinates, so if userspace rotates the picture to adjust for1547 *	the orientation it must also apply the same transformation to the1548 *	touchscreen input coordinates. This property is initialized by calling1549 *	drm_connector_set_panel_orientation() or1550 *	drm_connector_set_panel_orientation_with_quirk()1551 *1552 * scaling mode:1553 *	This property defines how a non-native mode is upscaled to the native1554 *	mode of an LCD panel:1555 *1556 *	None:1557 *		No upscaling happens, scaling is left to the panel. Not all1558 *		drivers expose this mode.1559 *	Full:1560 *		The output is upscaled to the full resolution of the panel,1561 *		ignoring the aspect ratio.1562 *	Center:1563 *		No upscaling happens, the output is centered within the native1564 *		resolution the panel.1565 *	Full aspect:1566 *		The output is upscaled to maximize either the width or height1567 *		while retaining the aspect ratio.1568 *1569 *	This property should be set up by calling1570 *	drm_connector_attach_scaling_mode_property(). Note that drivers1571 *	can also expose this property to external outputs, in which case they1572 *	must support "None", which should be the default (since external screens1573 *	have a built-in scaler).1574 *1575 * subconnector:1576 *	This property is used by DVI-I, TVout and DisplayPort to indicate different1577 *	connector subtypes. Enum values more or less match with those from main1578 *	connector types.1579 *	For DVI-I and TVout there is also a matching property "select subconnector"1580 *	allowing to switch between signal types.1581 *	DP subconnector corresponds to a downstream port.1582 *1583 * privacy-screen sw-state, privacy-screen hw-state:1584 *	These 2 optional properties can be used to query the state of the1585 *	electronic privacy screen that is available on some displays; and in1586 *	some cases also control the state. If a driver implements these1587 *	properties then both properties must be present.1588 *1589 *	"privacy-screen hw-state" is read-only and reflects the actual state1590 *	of the privacy-screen, possible values: "Enabled", "Disabled,1591 *	"Enabled-locked", "Disabled-locked". The locked states indicate1592 *	that the state cannot be changed through the DRM API. E.g. there1593 *	might be devices where the firmware-setup options, or a hardware1594 *	slider-switch, offer always on / off modes.1595 *1596 *	"privacy-screen sw-state" can be set to change the privacy-screen state1597 *	when not locked. In this case the driver must update the hw-state1598 *	property to reflect the new state on completion of the commit of the1599 *	sw-state property. Setting the sw-state property when the hw-state is1600 *	locked must be interpreted by the driver as a request to change the1601 *	state to the set state when the hw-state becomes unlocked. E.g. if1602 *	"privacy-screen hw-state" is "Enabled-locked" and the sw-state1603 *	gets set to "Disabled" followed by the user unlocking the state by1604 *	changing the slider-switch position, then the driver must set the1605 *	state to "Disabled" upon receiving the unlock event.1606 *1607 *	In some cases the privacy-screen's actual state might change outside of1608 *	control of the DRM code. E.g. there might be a firmware handled hotkey1609 *	which toggles the actual state, or the actual state might be changed1610 *	through another userspace API such as writing /proc/acpi/ibm/lcdshadow.1611 *	In this case the driver must update both the hw-state and the sw-state1612 *	to reflect the new value, overwriting any pending state requests in the1613 *	sw-state. Any pending sw-state requests are thus discarded.1614 *1615 *	Note that the ability for the state to change outside of control of1616 *	the DRM master process means that userspace must not cache the value1617 *	of the sw-state. Caching the sw-state value and including it in later1618 *	atomic commits may lead to overriding a state change done through e.g.1619 *	a firmware handled hotkey. Therefor userspace must not include the1620 *	privacy-screen sw-state in an atomic commit unless it wants to change1621 *	its value.1622 *1623 * left margin, right margin, top margin, bottom margin:1624 *	Add margins to the connector's viewport. This is typically used to1625 *	mitigate overscan on TVs.1626 *1627 *	The value is the size in pixels of the black border which will be1628 *	added. The attached CRTC's content will be scaled to fill the whole1629 *	area inside the margin.1630 *1631 *	The margins configuration might be sent to the sink, e.g. via HDMI AVI1632 *	InfoFrames.1633 *1634 *	Drivers can set up these properties by calling1635 *	drm_mode_create_tv_margin_properties().1636 */1637 1638int drm_connector_create_standard_properties(struct drm_device *dev)1639{1640	struct drm_property *prop;1641 1642	prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |1643				   DRM_MODE_PROP_IMMUTABLE,1644				   "EDID", 0);1645	if (!prop)1646		return -ENOMEM;1647	dev->mode_config.edid_property = prop;1648 1649	prop = drm_property_create_enum(dev, 0,1650				   "DPMS", drm_dpms_enum_list,1651				   ARRAY_SIZE(drm_dpms_enum_list));1652	if (!prop)1653		return -ENOMEM;1654	dev->mode_config.dpms_property = prop;1655 1656	prop = drm_property_create(dev,1657				   DRM_MODE_PROP_BLOB |1658				   DRM_MODE_PROP_IMMUTABLE,1659				   "PATH", 0);1660	if (!prop)1661		return -ENOMEM;1662	dev->mode_config.path_property = prop;1663 1664	prop = drm_property_create(dev,1665				   DRM_MODE_PROP_BLOB |1666				   DRM_MODE_PROP_IMMUTABLE,1667				   "TILE", 0);1668	if (!prop)1669		return -ENOMEM;1670	dev->mode_config.tile_property = prop;1671 1672	prop = drm_property_create_enum(dev, 0, "link-status",1673					drm_link_status_enum_list,1674					ARRAY_SIZE(drm_link_status_enum_list));1675	if (!prop)1676		return -ENOMEM;1677	dev->mode_config.link_status_property = prop;1678 1679	prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE, "non-desktop");1680	if (!prop)1681		return -ENOMEM;1682	dev->mode_config.non_desktop_property = prop;1683 1684	prop = drm_property_create(dev, DRM_MODE_PROP_BLOB,1685				   "HDR_OUTPUT_METADATA", 0);1686	if (!prop)1687		return -ENOMEM;1688	dev->mode_config.hdr_output_metadata_property = prop;1689 1690	return 0;1691}1692 1693/**1694 * drm_mode_create_dvi_i_properties - create DVI-I specific connector properties1695 * @dev: DRM device1696 *1697 * Called by a driver the first time a DVI-I connector is made.1698 *1699 * Returns: %01700 */1701int drm_mode_create_dvi_i_properties(struct drm_device *dev)1702{1703	struct drm_property *dvi_i_selector;1704	struct drm_property *dvi_i_subconnector;1705 1706	if (dev->mode_config.dvi_i_select_subconnector_property)1707		return 0;1708 1709	dvi_i_selector =1710		drm_property_create_enum(dev, 0,1711				    "select subconnector",1712				    drm_dvi_i_select_enum_list,1713				    ARRAY_SIZE(drm_dvi_i_select_enum_list));1714	dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;1715 1716	dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,1717				    "subconnector",1718				    drm_dvi_i_subconnector_enum_list,1719				    ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));1720	dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;1721 1722	return 0;1723}1724EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);1725 1726/**1727 * drm_connector_attach_dp_subconnector_property - create subconnector property for DP1728 * @connector: drm_connector to attach property1729 *1730 * Called by a driver when DP connector is created.1731 */1732void drm_connector_attach_dp_subconnector_property(struct drm_connector *connector)1733{1734	struct drm_mode_config *mode_config = &connector->dev->mode_config;1735 1736	if (!mode_config->dp_subconnector_property)1737		mode_config->dp_subconnector_property =1738			drm_property_create_enum(connector->dev,1739				DRM_MODE_PROP_IMMUTABLE,1740				"subconnector",1741				drm_dp_subconnector_enum_list,1742				ARRAY_SIZE(drm_dp_subconnector_enum_list));1743 1744	drm_object_attach_property(&connector->base,1745				   mode_config->dp_subconnector_property,1746				   DRM_MODE_SUBCONNECTOR_Unknown);1747}1748EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);1749 1750/**1751 * DOC: HDMI connector properties1752 *1753 * Broadcast RGB (HDMI specific)1754 *      Indicates the Quantization Range (Full vs Limited) used. The color1755 *      processing pipeline will be adjusted to match the value of the1756 *      property, and the Infoframes will be generated and sent accordingly.1757 *1758 *      This property is only relevant if the HDMI output format is RGB. If1759 *      it's one of the YCbCr variant, it will be ignored.1760 *1761 *      The CRTC attached to the connector must be configured by user-space to1762 *      always produce full-range pixels.1763 *1764 *      The value of this property can be one of the following:1765 *1766 *      Automatic:1767 *              The quantization range is selected automatically based on the1768 *              mode according to the HDMI specifications (HDMI 1.4b - Section1769 *              6.6 - Video Quantization Ranges).1770 *1771 *      Full:1772 *              Full quantization range is forced.1773 *1774 *      Limited 16:235:1775 *              Limited quantization range is forced. Unlike the name suggests,1776 *              this works for any number of bits-per-component.1777 *1778 *      Property values other than Automatic can result in colors being off (if1779 *      limited is selected but the display expects full), or a black screen1780 *      (if full is selected but the display expects limited).1781 *1782 *      Drivers can set up this property by calling1783 *      drm_connector_attach_broadcast_rgb_property().1784 *1785 * content type (HDMI specific):1786 *	Indicates content type setting to be used in HDMI infoframes to indicate1787 *	content type for the external device, so that it adjusts its display1788 *	settings accordingly.1789 *1790 *	The value of this property can be one of the following:1791 *1792 *	No Data:1793 *		Content type is unknown1794 *	Graphics:1795 *		Content type is graphics1796 *	Photo:1797 *		Content type is photo1798 *	Cinema:1799 *		Content type is cinema1800 *	Game:1801 *		Content type is game1802 *1803 *	The meaning of each content type is defined in CTA-861-G table 15.1804 *1805 *	Drivers can set up this property by calling1806 *	drm_connector_attach_content_type_property(). Decoding to1807 *	infoframe values is done through drm_hdmi_avi_infoframe_content_type().1808 */1809 1810/*1811 * TODO: Document the properties:1812 *   - brightness1813 *   - contrast1814 *   - flicker reduction1815 *   - hue1816 *   - mode1817 *   - overscan1818 *   - saturation1819 *   - select subconnector1820 */1821/**1822 * DOC: Analog TV Connector Properties1823 *1824 * TV Mode:1825 *	Indicates the TV Mode used on an analog TV connector. The value1826 *	of this property can be one of the following:1827 *1828 *	NTSC:1829 *		TV Mode is CCIR System M (aka 525-lines) together with1830 *		the NTSC Color Encoding.1831 *1832 *	NTSC-443:1833 *1834 *		TV Mode is CCIR System M (aka 525-lines) together with1835 *		the NTSC Color Encoding, but with a color subcarrier1836 *		frequency of 4.43MHz1837 *1838 *	NTSC-J:1839 *1840 *		TV Mode is CCIR System M (aka 525-lines) together with1841 *		the NTSC Color Encoding, but with a black level equal to1842 *		the blanking level.1843 *1844 *	PAL:1845 *1846 *		TV Mode is CCIR System B (aka 625-lines) together with1847 *		the PAL Color Encoding.1848 *1849 *	PAL-M:1850 *1851 *		TV Mode is CCIR System M (aka 525-lines) together with1852 *		the PAL Color Encoding.1853 *1854 *	PAL-N:1855 *1856 *		TV Mode is CCIR System N together with the PAL Color1857 *		Encoding, a color subcarrier frequency of 3.58MHz, the1858 *		SECAM color space, and narrower channels than other PAL1859 *		variants.1860 *1861 *	SECAM:1862 *1863 *		TV Mode is CCIR System B (aka 625-lines) together with1864 *		the SECAM Color Encoding.1865 *1866 *	Mono:1867 *1868 *		Use timings appropriate to the DRM mode, including1869 *		equalizing pulses for a 525-line or 625-line mode,1870 *		with no pedestal or color encoding.1871 *1872 *	Drivers can set up this property by calling1873 *	drm_mode_create_tv_properties().1874 */1875 1876/**1877 * drm_connector_attach_content_type_property - attach content-type property1878 * @connector: connector to attach content type property on.1879 *1880 * Called by a driver the first time a HDMI connector is made.1881 *1882 * Returns: %01883 */1884int drm_connector_attach_content_type_property(struct drm_connector *connector)1885{1886	if (!drm_mode_create_content_type_property(connector->dev))1887		drm_object_attach_property(&connector->base,1888					   connector->dev->mode_config.content_type_property,1889					   DRM_MODE_CONTENT_TYPE_NO_DATA);1890	return 0;1891}1892EXPORT_SYMBOL(drm_connector_attach_content_type_property);1893 1894/**1895 * drm_connector_attach_tv_margin_properties - attach TV connector margin1896 * 	properties1897 * @connector: DRM connector1898 *1899 * Called by a driver when it needs to attach TV margin props to a connector.1900 * Typically used on SDTV and HDMI connectors.1901 */1902void drm_connector_attach_tv_margin_properties(struct drm_connector *connector)1903{1904	struct drm_device *dev = connector->dev;1905 1906	drm_object_attach_property(&connector->base,1907				   dev->mode_config.tv_left_margin_property,1908				   0);1909	drm_object_attach_property(&connector->base,1910				   dev->mode_config.tv_right_margin_property,1911				   0);1912	drm_object_attach_property(&connector->base,1913				   dev->mode_config.tv_top_margin_property,1914				   0);1915	drm_object_attach_property(&connector->base,1916				   dev->mode_config.tv_bottom_margin_property,1917				   0);1918}1919EXPORT_SYMBOL(drm_connector_attach_tv_margin_properties);1920 1921/**1922 * drm_mode_create_tv_margin_properties - create TV connector margin properties1923 * @dev: DRM device1924 *1925 * Called by a driver's HDMI connector initialization routine, this function1926 * creates the TV margin properties for a given device. No need to call this1927 * function for an SDTV connector, it's already called from1928 * drm_mode_create_tv_properties_legacy().1929 *1930 * Returns:1931 * 0 on success or a negative error code on failure.1932 */1933int drm_mode_create_tv_margin_properties(struct drm_device *dev)1934{1935	if (dev->mode_config.tv_left_margin_property)1936		return 0;1937 1938	dev->mode_config.tv_left_margin_property =1939		drm_property_create_range(dev, 0, "left margin", 0, 100);1940	if (!dev->mode_config.tv_left_margin_property)1941		return -ENOMEM;1942 1943	dev->mode_config.tv_right_margin_property =1944		drm_property_create_range(dev, 0, "right margin", 0, 100);1945	if (!dev->mode_config.tv_right_margin_property)1946		return -ENOMEM;1947 1948	dev->mode_config.tv_top_margin_property =1949		drm_property_create_range(dev, 0, "top margin", 0, 100);1950	if (!dev->mode_config.tv_top_margin_property)1951		return -ENOMEM;1952 1953	dev->mode_config.tv_bottom_margin_property =1954		drm_property_create_range(dev, 0, "bottom margin", 0, 100);1955	if (!dev->mode_config.tv_bottom_margin_property)1956		return -ENOMEM;1957 1958	return 0;1959}1960EXPORT_SYMBOL(drm_mode_create_tv_margin_properties);1961 1962/**1963 * drm_mode_create_tv_properties_legacy - create TV specific connector properties1964 * @dev: DRM device1965 * @num_modes: number of different TV formats (modes) supported1966 * @modes: array of pointers to strings containing name of each format1967 *1968 * Called by a driver's TV initialization routine, this function creates1969 * the TV specific connector properties for a given device.  Caller is1970 * responsible for allocating a list of format names and passing them to1971 * this routine.1972 *1973 * NOTE: This functions registers the deprecated "mode" connector1974 * property to select the analog TV mode (ie, NTSC, PAL, etc.). New1975 * drivers must use drm_mode_create_tv_properties() instead.1976 *1977 * Returns:1978 * 0 on success or a negative error code on failure.1979 */1980int drm_mode_create_tv_properties_legacy(struct drm_device *dev,1981					 unsigned int num_modes,1982					 const char * const modes[])1983{1984	struct drm_property *tv_selector;1985	struct drm_property *tv_subconnector;1986	unsigned int i;1987 1988	if (dev->mode_config.tv_select_subconnector_property)1989		return 0;1990 1991	/*1992	 * Basic connector properties1993	 */1994	tv_selector = drm_property_create_enum(dev, 0,1995					  "select subconnector",1996					  drm_tv_select_enum_list,1997					  ARRAY_SIZE(drm_tv_select_enum_list));1998	if (!tv_selector)1999		goto nomem;2000 2001	dev->mode_config.tv_select_subconnector_property = tv_selector;2002 2003	tv_subconnector =2004		drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,2005				    "subconnector",2006				    drm_tv_subconnector_enum_list,2007				    ARRAY_SIZE(drm_tv_subconnector_enum_list));2008	if (!tv_subconnector)2009		goto nomem;2010	dev->mode_config.tv_subconnector_property = tv_subconnector;2011 2012	/*2013	 * Other, TV specific properties: margins & TV modes.2014	 */2015	if (drm_mode_create_tv_margin_properties(dev))2016		goto nomem;2017 2018	if (num_modes) {2019		dev->mode_config.legacy_tv_mode_property =2020			drm_property_create(dev, DRM_MODE_PROP_ENUM,2021					    "mode", num_modes);2022		if (!dev->mode_config.legacy_tv_mode_property)2023			goto nomem;2024 2025		for (i = 0; i < num_modes; i++)2026			drm_property_add_enum(dev->mode_config.legacy_tv_mode_property,2027					      i, modes[i]);2028	}2029 2030	dev->mode_config.tv_brightness_property =2031		drm_property_create_range(dev, 0, "brightness", 0, 100);2032	if (!dev->mode_config.tv_brightness_property)2033		goto nomem;2034 2035	dev->mode_config.tv_contrast_property =2036		drm_property_create_range(dev, 0, "contrast", 0, 100);2037	if (!dev->mode_config.tv_contrast_property)2038		goto nomem;2039 2040	dev->mode_config.tv_flicker_reduction_property =2041		drm_property_create_range(dev, 0, "flicker reduction", 0, 100);2042	if (!dev->mode_config.tv_flicker_reduction_property)2043		goto nomem;2044 2045	dev->mode_config.tv_overscan_property =2046		drm_property_create_range(dev, 0, "overscan", 0, 100);2047	if (!dev->mode_config.tv_overscan_property)2048		goto nomem;2049 2050	dev->mode_config.tv_saturation_property =2051		drm_property_create_range(dev, 0, "saturation", 0, 100);2052	if (!dev->mode_config.tv_saturation_property)2053		goto nomem;2054 2055	dev->mode_config.tv_hue_property =2056		drm_property_create_range(dev, 0, "hue", 0, 100);2057	if (!dev->mode_config.tv_hue_property)2058		goto nomem;2059 2060	return 0;2061nomem:2062	return -ENOMEM;2063}2064EXPORT_SYMBOL(drm_mode_create_tv_properties_legacy);2065 2066/**2067 * drm_mode_create_tv_properties - create TV specific connector properties2068 * @dev: DRM device2069 * @supported_tv_modes: Bitmask of TV modes supported (See DRM_MODE_TV_MODE_*)2070 *2071 * Called by a driver's TV initialization routine, this function creates2072 * the TV specific connector properties for a given device.2073 *2074 * Returns:2075 * 0 on success or a negative error code on failure.2076 */2077int drm_mode_create_tv_properties(struct drm_device *dev,2078				  unsigned int supported_tv_modes)2079{2080	struct drm_prop_enum_list tv_mode_list[DRM_MODE_TV_MODE_MAX];2081	struct drm_property *tv_mode;2082	unsigned int i, len = 0;2083 2084	if (dev->mode_config.tv_mode_property)2085		return 0;2086 2087	for (i = 0; i < DRM_MODE_TV_MODE_MAX; i++) {2088		if (!(supported_tv_modes & BIT(i)))2089			continue;2090 2091		tv_mode_list[len].type = i;2092		tv_mode_list[len].name = drm_get_tv_mode_name(i);2093		len++;2094	}2095 2096	tv_mode = drm_property_create_enum(dev, 0, "TV mode",2097					   tv_mode_list, len);2098	if (!tv_mode)2099		return -ENOMEM;2100 2101	dev->mode_config.tv_mode_property = tv_mode;2102 2103	return drm_mode_create_tv_properties_legacy(dev, 0, NULL);2104}2105EXPORT_SYMBOL(drm_mode_create_tv_properties);2106 2107/**2108 * drm_mode_create_scaling_mode_property - create scaling mode property2109 * @dev: DRM device2110 *2111 * Called by a driver the first time it's needed, must be attached to desired2112 * connectors.2113 *2114 * Atomic drivers should use drm_connector_attach_scaling_mode_property()2115 * instead to correctly assign &drm_connector_state.scaling_mode2116 * in the atomic state.2117 *2118 * Returns: %02119 */2120int drm_mode_create_scaling_mode_property(struct drm_device *dev)2121{2122	struct drm_property *scaling_mode;2123 2124	if (dev->mode_config.scaling_mode_property)2125		return 0;2126 2127	scaling_mode =2128		drm_property_create_enum(dev, 0, "scaling mode",2129				drm_scaling_mode_enum_list,2130				    ARRAY_SIZE(drm_scaling_mode_enum_list));2131 2132	dev->mode_config.scaling_mode_property = scaling_mode;2133 2134	return 0;2135}2136EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);2137 2138/**2139 * DOC: Variable refresh properties2140 *2141 * Variable refresh rate capable displays can dynamically adjust their2142 * refresh rate by extending the duration of their vertical front porch2143 * until page flip or timeout occurs. This can reduce or remove stuttering2144 * and latency in scenarios where the page flip does not align with the2145 * vblank interval.2146 *2147 * An example scenario would be an application flipping at a constant rate2148 * of 48Hz on a 60Hz display. The page flip will frequently miss the vblank2149 * interval and the same contents will be displayed twice. This can be2150 * observed as stuttering for content with motion.2151 *2152 * If variable refresh rate was active on a display that supported a2153 * variable refresh range from 35Hz to 60Hz no stuttering would be observable2154 * for the example scenario. The minimum supported variable refresh rate of2155 * 35Hz is below the page flip frequency and the vertical front porch can2156 * be extended until the page flip occurs. The vblank interval will be2157 * directly aligned to the page flip rate.2158 *2159 * Not all userspace content is suitable for use with variable refresh rate.2160 * Large and frequent changes in vertical front porch duration may worsen2161 * perceived stuttering for input sensitive applications.2162 *2163 * Panel brightness will also vary with vertical front porch duration. Some2164 * panels may have noticeable differences in brightness between the minimum2165 * vertical front porch duration and the maximum vertical front porch duration.2166 * Large and frequent changes in vertical front porch duration may produce2167 * observable flickering for such panels.2168 *2169 * Userspace control for variable refresh rate is supported via properties2170 * on the &drm_connector and &drm_crtc objects.2171 *2172 * "vrr_capable":2173 *	Optional &drm_connector boolean property that drivers should attach2174 *	with drm_connector_attach_vrr_capable_property() on connectors that2175 *	could support variable refresh rates. Drivers should update the2176 *	property value by calling drm_connector_set_vrr_capable_property().2177 *2178 *	Absence of the property should indicate absence of support.2179 *2180 * "VRR_ENABLED":2181 *	Default &drm_crtc boolean property that notifies the driver that the2182 *	content on the CRTC is suitable for variable refresh rate presentation.2183 *	The driver will take this property as a hint to enable variable2184 *	refresh rate support if the receiver supports it, ie. if the2185 *	"vrr_capable" property is true on the &drm_connector object. The2186 *	vertical front porch duration will be extended until page-flip or2187 *	timeout when enabled.2188 *2189 *	The minimum vertical front porch duration is defined as the vertical2190 *	front porch duration for the current mode.2191 *2192 *	The maximum vertical front porch duration is greater than or equal to2193 *	the minimum vertical front porch duration. The duration is derived2194 *	from the minimum supported variable refresh rate for the connector.2195 *2196 *	The driver may place further restrictions within these minimum2197 *	and maximum bounds.2198 */2199 2200/**2201 * drm_connector_attach_vrr_capable_property - creates the2202 * vrr_capable property2203 * @connector: connector to create the vrr_capable property on.2204 *2205 * This is used by atomic drivers to add support for querying2206 * variable refresh rate capability for a connector.2207 *2208 * Returns:2209 * Zero on success, negative errno on failure.2210 */2211int drm_connector_attach_vrr_capable_property(2212	struct drm_connector *connector)2213{2214	struct drm_device *dev = connector->dev;2215	struct drm_property *prop;2216 2217	if (!connector->vrr_capable_property) {2218		prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE,2219			"vrr_capable");2220		if (!prop)2221			return -ENOMEM;2222 2223		connector->vrr_capable_property = prop;2224		drm_object_attach_property(&connector->base, prop, 0);2225	}2226 2227	return 0;2228}2229EXPORT_SYMBOL(drm_connector_attach_vrr_capable_property);2230 2231/**2232 * drm_connector_attach_scaling_mode_property - attach atomic scaling mode property2233 * @connector: connector to attach scaling mode property on.2234 * @scaling_mode_mask: or'ed mask of BIT(%DRM_MODE_SCALE_\*).2235 *2236 * This is used to add support for scaling mode to atomic drivers.2237 * The scaling mode will be set to &drm_connector_state.scaling_mode2238 * and can be used from &drm_connector_helper_funcs->atomic_check for validation.2239 *2240 * This is the atomic version of drm_mode_create_scaling_mode_property().2241 *2242 * Returns:2243 * Zero on success, negative errno on failure.2244 */2245int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,2246					       u32 scaling_mode_mask)2247{2248	struct drm_device *dev = connector->dev;2249	struct drm_property *scaling_mode_property;2250	int i;2251	const unsigned valid_scaling_mode_mask =2252		(1U << ARRAY_SIZE(drm_scaling_mode_enum_list)) - 1;2253 2254	if (WARN_ON(hweight32(scaling_mode_mask) < 2 ||2255		    scaling_mode_mask & ~valid_scaling_mode_mask))2256		return -EINVAL;2257 2258	scaling_mode_property =2259		drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",2260				    hweight32(scaling_mode_mask));2261 2262	if (!scaling_mode_property)2263		return -ENOMEM;2264 2265	for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++) {2266		int ret;2267 2268		if (!(BIT(i) & scaling_mode_mask))2269			continue;2270 2271		ret = drm_property_add_enum(scaling_mode_property,2272					    drm_scaling_mode_enum_list[i].type,2273					    drm_scaling_mode_enum_list[i].name);2274 2275		if (ret) {2276			drm_property_destroy(dev, scaling_mode_property);2277 2278			return ret;2279		}2280	}2281 2282	drm_object_attach_property(&connector->base,2283				   scaling_mode_property, 0);2284 2285	connector->scaling_mode_property = scaling_mode_property;2286 2287	return 0;2288}2289EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);2290 2291/**2292 * drm_mode_create_aspect_ratio_property - create aspect ratio property2293 * @dev: DRM device2294 *2295 * Called by a driver the first time it's needed, must be attached to desired2296 * connectors.2297 *2298 * Returns:2299 * Zero on success, negative errno on failure.2300 */2301int drm_mode_create_aspect_ratio_property(struct drm_device *dev)2302{2303	if (dev->mode_config.aspect_ratio_property)2304		return 0;2305 2306	dev->mode_config.aspect_ratio_property =2307		drm_property_create_enum(dev, 0, "aspect ratio",2308				drm_aspect_ratio_enum_list,2309				ARRAY_SIZE(drm_aspect_ratio_enum_list));2310 2311	if (dev->mode_config.aspect_ratio_property == NULL)2312		return -ENOMEM;2313 2314	return 0;2315}2316EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);2317 2318/**2319 * DOC: standard connector properties2320 *2321 * Colorspace:2322 *	This property is used to inform the driver about the color encoding2323 *	user space configured the pixel operation properties to produce.2324 *	The variants set the colorimetry, transfer characteristics, and which2325 *	YCbCr conversion should be used when necessary.2326 *	The transfer characteristics from HDR_OUTPUT_METADATA takes precedence2327 *	over this property.2328 *	User space always configures the pixel operation properties to produce2329 *	full quantization range data (see the Broadcast RGB property).2330 *2331 *	Drivers inform the sink about what colorimetry, transfer2332 *	characteristics, YCbCr conversion, and quantization range to expect2333 *	(this can depend on the output mode, output format and other2334 *	properties). Drivers also convert the user space provided data to what2335 *	the sink expects.2336 *2337 *	User space has to check if the sink supports all of the possible2338 *	colorimetries that the driver is allowed to pick by parsing the EDID.2339 *2340 *	For historical reasons this property exposes a number of variants which2341 *	result in undefined behavior.2342 *2343 *	Default:2344 *		The behavior is driver-specific.2345 *2346 *	BT2020_RGB:2347 *2348 *	BT2020_YCC:2349 *		User space configures the pixel operation properties to produce2350 *		RGB content with Rec. ITU-R BT.2020 colorimetry, Rec.2351 *		ITU-R BT.2020 (Table 4, RGB) transfer characteristics and full2352 *		quantization range.2353 *		User space can use the HDR_OUTPUT_METADATA property to set the2354 *		transfer characteristics to PQ (Rec. ITU-R BT.2100 Table 4) or2355 *		HLG (Rec. ITU-R BT.2100 Table 5) in which case, user space2356 *		configures pixel operation properties to produce content with2357 *		the respective transfer characteristics.2358 *		User space has to make sure the sink supports Rec.2359 *		ITU-R BT.2020 R'G'B' and Rec. ITU-R BT.2020 Y'C'BC'R2360 *		colorimetry.2361 *		Drivers can configure the sink to use an RGB format, tell the2362 *		sink to expect Rec. ITU-R BT.2020 R'G'B' colorimetry and convert2363 *		to the appropriate quantization range.2364 *		Drivers can configure the sink to use a YCbCr format, tell the2365 *		sink to expect Rec. ITU-R BT.2020 Y'C'BC'R colorimetry, convert2366 *		to YCbCr using the Rec. ITU-R BT.2020 non-constant luminance2367 *		conversion matrix and convert to the appropriate quantization2368 *		range.2369 *		The variants BT2020_RGB and BT2020_YCC are equivalent and the2370 *		driver chooses between RGB and YCbCr on its own.2371 *2372 *	SMPTE_170M_YCC:2373 *	BT709_YCC:2374 *	XVYCC_601:2375 *	XVYCC_709:2376 *	SYCC_601:2377 *	opYCC_601:2378 *	opRGB:2379 *	BT2020_CYCC:2380 *	DCI-P3_RGB_D65:2381 *	DCI-P3_RGB_Theater:2382 *	RGB_WIDE_FIXED:2383 *	RGB_WIDE_FLOAT:2384 *2385 *	BT601_YCC:2386 *		The behavior is undefined.2387 *2388 * Because between HDMI and DP have different colorspaces,2389 * drm_mode_create_hdmi_colorspace_property() is used for HDMI connector and2390 * drm_mode_create_dp_colorspace_property() is used for DP connector.2391 */2392 2393static int drm_mode_create_colorspace_property(struct drm_connector *connector,2394					u32 supported_colorspaces)2395{2396	struct drm_device *dev = connector->dev;2397	u32 colorspaces = supported_colorspaces | BIT(DRM_MODE_COLORIMETRY_DEFAULT);2398	struct drm_prop_enum_list enum_list[DRM_MODE_COLORIMETRY_COUNT];2399	int i, len;2400 2401	if (connector->colorspace_property)2402		return 0;2403 2404	if (!supported_colorspaces) {2405		drm_err(dev, "No supported colorspaces provded on [CONNECTOR:%d:%s]\n",2406			    connector->base.id, connector->name);2407		return -EINVAL;2408	}2409 2410	if ((supported_colorspaces & -BIT(DRM_MODE_COLORIMETRY_COUNT)) != 0) {2411		drm_err(dev, "Unknown colorspace provded on [CONNECTOR:%d:%s]\n",2412			    connector->base.id, connector->name);2413		return -EINVAL;2414	}2415 2416	len = 0;2417	for (i = 0; i < DRM_MODE_COLORIMETRY_COUNT; i++) {2418		if ((colorspaces & BIT(i)) == 0)2419			continue;2420 2421		enum_list[len].type = i;2422		enum_list[len].name = colorspace_names[i];2423		len++;2424	}2425 2426	connector->colorspace_property =2427		drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, "Colorspace",2428					enum_list,2429					len);2430 2431	if (!connector->colorspace_property)2432		return -ENOMEM;2433 2434	return 0;2435}2436 2437/**2438 * drm_mode_create_hdmi_colorspace_property - create hdmi colorspace property2439 * @connector: connector to create the Colorspace property on.2440 * @supported_colorspaces: bitmap of supported color spaces2441 *2442 * Called by a driver the first time it's needed, must be attached to desired2443 * HDMI connectors.2444 *2445 * Returns:2446 * Zero on success, negative errno on failure.2447 */2448int drm_mode_create_hdmi_colorspace_property(struct drm_connector *connector,2449					     u32 supported_colorspaces)2450{2451	u32 colorspaces;2452 2453	if (supported_colorspaces)2454		colorspaces = supported_colorspaces & hdmi_colorspaces;2455	else2456		colorspaces = hdmi_colorspaces;2457 2458	return drm_mode_create_colorspace_property(connector, colorspaces);2459}2460EXPORT_SYMBOL(drm_mode_create_hdmi_colorspace_property);2461 2462/**2463 * drm_mode_create_dp_colorspace_property - create dp colorspace property2464 * @connector: connector to create the Colorspace property on.2465 * @supported_colorspaces: bitmap of supported color spaces2466 *2467 * Called by a driver the first time it's needed, must be attached to desired2468 * DP connectors.2469 *2470 * Returns:2471 * Zero on success, negative errno on failure.2472 */2473int drm_mode_create_dp_colorspace_property(struct drm_connector *connector,2474					   u32 supported_colorspaces)2475{2476	u32 colorspaces;2477 2478	if (supported_colorspaces)2479		colorspaces = supported_colorspaces & dp_colorspaces;2480	else2481		colorspaces = dp_colorspaces;2482 2483	return drm_mode_create_colorspace_property(connector, colorspaces);2484}2485EXPORT_SYMBOL(drm_mode_create_dp_colorspace_property);2486 2487/**2488 * drm_mode_create_content_type_property - create content type property2489 * @dev: DRM device2490 *2491 * Called by a driver the first time it's needed, must be attached to desired2492 * connectors.2493 *2494 * Returns:2495 * Zero on success, negative errno on failure.2496 */2497int drm_mode_create_content_type_property(struct drm_device *dev)2498{2499	if (dev->mode_config.content_type_property)2500		return 0;2501 2502	dev->mode_config.content_type_property =2503		drm_property_create_enum(dev, 0, "content type",2504					 drm_content_type_enum_list,2505					 ARRAY_SIZE(drm_content_type_enum_list));2506 2507	if (dev->mode_config.content_type_property == NULL)2508		return -ENOMEM;2509 2510	return 0;2511}2512EXPORT_SYMBOL(drm_mode_create_content_type_property);2513 2514/**2515 * drm_mode_create_suggested_offset_properties - create suggests offset properties2516 * @dev: DRM device2517 *2518 * Create the suggested x/y offset property for connectors.2519 *2520 * Returns:2521 * 0 on success or a negative error code on failure.2522 */2523int drm_mode_create_suggested_offset_properties(struct drm_device *dev)2524{2525	if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property)2526		return 0;2527 2528	dev->mode_config.suggested_x_property =2529		drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff);2530 2531	dev->mode_config.suggested_y_property =2532		drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff);2533 2534	if (dev->mode_config.suggested_x_property == NULL ||2535	    dev->mode_config.suggested_y_property == NULL)2536		return -ENOMEM;2537	return 0;2538}2539EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);2540 2541/**2542 * drm_connector_set_path_property - set tile property on connector2543 * @connector: connector to set property on.2544 * @path: path to use for property; must not be NULL.2545 *2546 * This creates a property to expose to userspace to specify a2547 * connector path. This is mainly used for DisplayPort MST where2548 * connectors have a topology and we want to allow userspace to give2549 * them more meaningful names.2550 *2551 * Returns:2552 * Zero on success, negative errno on failure.2553 */2554int drm_connector_set_path_property(struct drm_connector *connector,2555				    const char *path)2556{2557	struct drm_device *dev = connector->dev;2558	int ret;2559 2560	ret = drm_property_replace_global_blob(dev,2561					       &connector->path_blob_ptr,2562					       strlen(path) + 1,2563					       path,2564					       &connector->base,2565					       dev->mode_config.path_property);2566	return ret;2567}2568EXPORT_SYMBOL(drm_connector_set_path_property);2569 2570/**2571 * drm_connector_set_tile_property - set tile property on connector2572 * @connector: connector to set property on.2573 *2574 * This looks up the tile information for a connector, and creates a2575 * property for userspace to parse if it exists. The property is of2576 * the form of 8 integers using ':' as a separator.2577 * This is used for dual port tiled displays with DisplayPort SST2578 * or DisplayPort MST connectors.2579 *2580 * Returns:2581 * Zero on success, errno on failure.2582 */2583int drm_connector_set_tile_property(struct drm_connector *connector)2584{2585	struct drm_device *dev = connector->dev;2586	char tile[256];2587	int ret;2588 2589	if (!connector->has_tile) {2590		ret  = drm_property_replace_global_blob(dev,2591							&connector->tile_blob_ptr,2592							0,2593							NULL,2594							&connector->base,2595							dev->mode_config.tile_property);2596		return ret;2597	}2598 2599	snprintf(tile, 256, "%d:%d:%d:%d:%d:%d:%d:%d",2600		 connector->tile_group->id, connector->tile_is_single_monitor,2601		 connector->num_h_tile, connector->num_v_tile,2602		 connector->tile_h_loc, connector->tile_v_loc,2603		 connector->tile_h_size, connector->tile_v_size);2604 2605	ret = drm_property_replace_global_blob(dev,2606					       &connector->tile_blob_ptr,2607					       strlen(tile) + 1,2608					       tile,2609					       &connector->base,2610					       dev->mode_config.tile_property);2611	return ret;2612}2613EXPORT_SYMBOL(drm_connector_set_tile_property);2614 2615/**2616 * drm_connector_set_link_status_property - Set link status property of a connector2617 * @connector: drm connector2618 * @link_status: new value of link status property (0: Good, 1: Bad)2619 *2620 * In usual working scenario, this link status property will always be set to2621 * "GOOD". If something fails during or after a mode set, the kernel driver2622 * may set this link status property to "BAD". The caller then needs to send a2623 * hotplug uevent for userspace to re-check the valid modes through2624 * GET_CONNECTOR_IOCTL and retry modeset.2625 *2626 * Note: Drivers cannot rely on userspace to support this property and2627 * issue a modeset. As such, they may choose to handle issues (like2628 * re-training a link) without userspace's intervention.2629 *2630 * The reason for adding this property is to handle link training failures, but2631 * it is not limited to DP or link training. For example, if we implement2632 * asynchronous setcrtc, this property can be used to report any failures in that.2633 */2634void drm_connector_set_link_status_property(struct drm_connector *connector,2635					    uint64_t link_status)2636{2637	struct drm_device *dev = connector->dev;2638 2639	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);2640	connector->state->link_status = link_status;2641	drm_modeset_unlock(&dev->mode_config.connection_mutex);2642}2643EXPORT_SYMBOL(drm_connector_set_link_status_property);2644 2645/**2646 * drm_connector_attach_max_bpc_property - attach "max bpc" property2647 * @connector: connector to attach max bpc property on.2648 * @min: The minimum bit depth supported by the connector.2649 * @max: The maximum bit depth supported by the connector.2650 *2651 * This is used to add support for limiting the bit depth on a connector.2652 *2653 * Returns:2654 * Zero on success, negative errno on failure.2655 */2656int drm_connector_attach_max_bpc_property(struct drm_connector *connector,2657					  int min, int max)2658{2659	struct drm_device *dev = connector->dev;2660	struct drm_property *prop;2661 2662	prop = connector->max_bpc_property;2663	if (!prop) {2664		prop = drm_property_create_range(dev, 0, "max bpc", min, max);2665		if (!prop)2666			return -ENOMEM;2667 2668		connector->max_bpc_property = prop;2669	}2670 2671	drm_object_attach_property(&connector->base, prop, max);2672	connector->state->max_requested_bpc = max;2673	connector->state->max_bpc = max;2674 2675	return 0;2676}2677EXPORT_SYMBOL(drm_connector_attach_max_bpc_property);2678 2679/**2680 * drm_connector_attach_hdr_output_metadata_property - attach "HDR_OUTPUT_METADA" property2681 * @connector: connector to attach the property on.2682 *2683 * This is used to allow the userspace to send HDR Metadata to the2684 * driver.2685 *2686 * Returns:2687 * Zero on success, negative errno on failure.2688 */2689int drm_connector_attach_hdr_output_metadata_property(struct drm_connector *connector)2690{2691	struct drm_device *dev = connector->dev;2692	struct drm_property *prop = dev->mode_config.hdr_output_metadata_property;2693 2694	drm_object_attach_property(&connector->base, prop, 0);2695 2696	return 0;2697}2698EXPORT_SYMBOL(drm_connector_attach_hdr_output_metadata_property);2699 2700/**2701 * drm_connector_attach_broadcast_rgb_property - attach "Broadcast RGB" property2702 * @connector: connector to attach the property on.2703 *2704 * This is used to add support for forcing the RGB range on a connector2705 *2706 * Returns:2707 * Zero on success, negative errno on failure.2708 */2709int drm_connector_attach_broadcast_rgb_property(struct drm_connector *connector)2710{2711	struct drm_device *dev = connector->dev;2712	struct drm_property *prop;2713 2714	prop = connector->broadcast_rgb_property;2715	if (!prop) {2716		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,2717						"Broadcast RGB",2718						broadcast_rgb_names,2719						ARRAY_SIZE(broadcast_rgb_names));2720		if (!prop)2721			return -EINVAL;2722 2723		connector->broadcast_rgb_property = prop;2724	}2725 2726	drm_object_attach_property(&connector->base, prop,2727				   DRM_HDMI_BROADCAST_RGB_AUTO);2728 2729	return 0;2730}2731EXPORT_SYMBOL(drm_connector_attach_broadcast_rgb_property);2732 2733/**2734 * drm_connector_attach_colorspace_property - attach "Colorspace" property2735 * @connector: connector to attach the property on.2736 *2737 * This is used to allow the userspace to signal the output colorspace2738 * to the driver.2739 *2740 * Returns:2741 * Zero on success, negative errno on failure.2742 */2743int drm_connector_attach_colorspace_property(struct drm_connector *connector)2744{2745	struct drm_property *prop = connector->colorspace_property;2746 2747	drm_object_attach_property(&connector->base, prop, DRM_MODE_COLORIMETRY_DEFAULT);2748 2749	return 0;2750}2751EXPORT_SYMBOL(drm_connector_attach_colorspace_property);2752 2753/**2754 * drm_connector_atomic_hdr_metadata_equal - checks if the hdr metadata changed2755 * @old_state: old connector state to compare2756 * @new_state: new connector state to compare2757 *2758 * This is used by HDR-enabled drivers to test whether the HDR metadata2759 * have changed between two different connector state (and thus probably2760 * requires a full blown mode change).2761 *2762 * Returns:2763 * True if the metadata are equal, False otherwise2764 */2765bool drm_connector_atomic_hdr_metadata_equal(struct drm_connector_state *old_state,2766					     struct drm_connector_state *new_state)2767{2768	struct drm_property_blob *old_blob = old_state->hdr_output_metadata;2769	struct drm_property_blob *new_blob = new_state->hdr_output_metadata;2770 2771	if (!old_blob || !new_blob)2772		return old_blob == new_blob;2773 2774	if (old_blob->length != new_blob->length)2775		return false;2776 2777	return !memcmp(old_blob->data, new_blob->data, old_blob->length);2778}2779EXPORT_SYMBOL(drm_connector_atomic_hdr_metadata_equal);2780 2781/**2782 * drm_connector_set_vrr_capable_property - sets the variable refresh rate2783 * capable property for a connector2784 * @connector: drm connector2785 * @capable: True if the connector is variable refresh rate capable2786 *2787 * Should be used by atomic drivers to update the indicated support for2788 * variable refresh rate over a connector.2789 */2790void drm_connector_set_vrr_capable_property(2791		struct drm_connector *connector, bool capable)2792{2793	if (!connector->vrr_capable_property)2794		return;2795 2796	drm_object_property_set_value(&connector->base,2797				      connector->vrr_capable_property,2798				      capable);2799}2800EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);2801 2802/**2803 * drm_connector_set_panel_orientation - sets the connector's panel_orientation2804 * @connector: connector for which to set the panel-orientation property.2805 * @panel_orientation: drm_panel_orientation value to set2806 *2807 * This function sets the connector's panel_orientation and attaches2808 * a "panel orientation" property to the connector.2809 *2810 * Calling this function on a connector where the panel_orientation has2811 * already been set is a no-op (e.g. the orientation has been overridden with2812 * a kernel commandline option).2813 *2814 * It is allowed to call this function with a panel_orientation of2815 * DRM_MODE_PANEL_ORIENTATION_UNKNOWN, in which case it is a no-op.2816 *2817 * The function shouldn't be called in panel after drm is registered (i.e.2818 * drm_dev_register() is called in drm).2819 *2820 * Returns:2821 * Zero on success, negative errno on failure.2822 */2823int drm_connector_set_panel_orientation(2824	struct drm_connector *connector,2825	enum drm_panel_orientation panel_orientation)2826{2827	struct drm_device *dev = connector->dev;2828	struct drm_display_info *info = &connector->display_info;2829	struct drm_property *prop;2830 2831	/* Already set? */2832	if (info->panel_orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)2833		return 0;2834 2835	/* Don't attach the property if the orientation is unknown */2836	if (panel_orientation == DRM_MODE_PANEL_ORIENTATION_UNKNOWN)2837		return 0;2838 2839	info->panel_orientation = panel_orientation;2840 2841	prop = dev->mode_config.panel_orientation_property;2842	if (!prop) {2843		prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,2844				"panel orientation",2845				drm_panel_orientation_enum_list,2846				ARRAY_SIZE(drm_panel_orientation_enum_list));2847		if (!prop)2848			return -ENOMEM;2849 2850		dev->mode_config.panel_orientation_property = prop;2851	}2852 2853	drm_object_attach_property(&connector->base, prop,2854				   info->panel_orientation);2855	return 0;2856}2857EXPORT_SYMBOL(drm_connector_set_panel_orientation);2858 2859/**2860 * drm_connector_set_panel_orientation_with_quirk - set the2861 *	connector's panel_orientation after checking for quirks2862 * @connector: connector for which to init the panel-orientation property.2863 * @panel_orientation: drm_panel_orientation value to set2864 * @width: width in pixels of the panel, used for panel quirk detection2865 * @height: height in pixels of the panel, used for panel quirk detection2866 *2867 * Like drm_connector_set_panel_orientation(), but with a check for platform2868 * specific (e.g. DMI based) quirks overriding the passed in panel_orientation.2869 *2870 * Returns:2871 * Zero on success, negative errno on failure.2872 */2873int drm_connector_set_panel_orientation_with_quirk(2874	struct drm_connector *connector,2875	enum drm_panel_orientation panel_orientation,2876	int width, int height)2877{2878	int orientation_quirk;2879 2880	orientation_quirk = drm_get_panel_orientation_quirk(width, height);2881	if (orientation_quirk != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)2882		panel_orientation = orientation_quirk;2883 2884	return drm_connector_set_panel_orientation(connector,2885						   panel_orientation);2886}2887EXPORT_SYMBOL(drm_connector_set_panel_orientation_with_quirk);2888 2889/**2890 * drm_connector_set_orientation_from_panel -2891 *	set the connector's panel_orientation from panel's callback.2892 * @connector: connector for which to init the panel-orientation property.2893 * @panel: panel that can provide orientation information.2894 *2895 * Drm drivers should call this function before drm_dev_register().2896 * Orientation is obtained from panel's .get_orientation() callback.2897 *2898 * Returns:2899 * Zero on success, negative errno on failure.2900 */2901int drm_connector_set_orientation_from_panel(2902	struct drm_connector *connector,2903	struct drm_panel *panel)2904{2905	enum drm_panel_orientation orientation;2906 2907	if (panel && panel->funcs && panel->funcs->get_orientation)2908		orientation = panel->funcs->get_orientation(panel);2909	else2910		orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;2911 2912	return drm_connector_set_panel_orientation(connector, orientation);2913}2914EXPORT_SYMBOL(drm_connector_set_orientation_from_panel);2915 2916static const struct drm_prop_enum_list privacy_screen_enum[] = {2917	{ PRIVACY_SCREEN_DISABLED,		"Disabled" },2918	{ PRIVACY_SCREEN_ENABLED,		"Enabled" },2919	{ PRIVACY_SCREEN_DISABLED_LOCKED,	"Disabled-locked" },2920	{ PRIVACY_SCREEN_ENABLED_LOCKED,	"Enabled-locked" },2921};2922 2923/**2924 * drm_connector_create_privacy_screen_properties - create the drm connecter's2925 *    privacy-screen properties.2926 * @connector: connector for which to create the privacy-screen properties2927 *2928 * This function creates the "privacy-screen sw-state" and "privacy-screen2929 * hw-state" properties for the connector. They are not attached.2930 */2931void2932drm_connector_create_privacy_screen_properties(struct drm_connector *connector)2933{2934	if (connector->privacy_screen_sw_state_property)2935		return;2936 2937	/* Note sw-state only supports the first 2 values of the enum */2938	connector->privacy_screen_sw_state_property =2939		drm_property_create_enum(connector->dev, DRM_MODE_PROP_ENUM,2940				"privacy-screen sw-state",2941				privacy_screen_enum, 2);2942 2943	connector->privacy_screen_hw_state_property =2944		drm_property_create_enum(connector->dev,2945				DRM_MODE_PROP_IMMUTABLE | DRM_MODE_PROP_ENUM,2946				"privacy-screen hw-state",2947				privacy_screen_enum,2948				ARRAY_SIZE(privacy_screen_enum));2949}2950EXPORT_SYMBOL(drm_connector_create_privacy_screen_properties);2951 2952/**2953 * drm_connector_attach_privacy_screen_properties - attach the drm connecter's2954 *    privacy-screen properties.2955 * @connector: connector on which to attach the privacy-screen properties2956 *2957 * This function attaches the "privacy-screen sw-state" and "privacy-screen2958 * hw-state" properties to the connector. The initial state of both is set2959 * to "Disabled".2960 */2961void2962drm_connector_attach_privacy_screen_properties(struct drm_connector *connector)2963{2964	if (!connector->privacy_screen_sw_state_property)2965		return;2966 2967	drm_object_attach_property(&connector->base,2968				   connector->privacy_screen_sw_state_property,2969				   PRIVACY_SCREEN_DISABLED);2970 2971	drm_object_attach_property(&connector->base,2972				   connector->privacy_screen_hw_state_property,2973				   PRIVACY_SCREEN_DISABLED);2974}2975EXPORT_SYMBOL(drm_connector_attach_privacy_screen_properties);2976 2977static void drm_connector_update_privacy_screen_properties(2978	struct drm_connector *connector, bool set_sw_state)2979{2980	enum drm_privacy_screen_status sw_state, hw_state;2981 2982	drm_privacy_screen_get_state(connector->privacy_screen,2983				     &sw_state, &hw_state);2984 2985	if (set_sw_state)2986		connector->state->privacy_screen_sw_state = sw_state;2987	drm_object_property_set_value(&connector->base,2988			connector->privacy_screen_hw_state_property, hw_state);2989}2990 2991static int drm_connector_privacy_screen_notifier(2992	struct notifier_block *nb, unsigned long action, void *data)2993{2994	struct drm_connector *connector =2995		container_of(nb, struct drm_connector, privacy_screen_notifier);2996	struct drm_device *dev = connector->dev;2997 2998	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);2999	drm_connector_update_privacy_screen_properties(connector, true);3000	drm_modeset_unlock(&dev->mode_config.connection_mutex);3001 3002	drm_sysfs_connector_property_event(connector,3003					   connector->privacy_screen_sw_state_property);3004	drm_sysfs_connector_property_event(connector,3005					   connector->privacy_screen_hw_state_property);3006 3007	return NOTIFY_DONE;3008}3009 3010/**3011 * drm_connector_attach_privacy_screen_provider - attach a privacy-screen to3012 *    the connector3013 * @connector: connector to attach the privacy-screen to3014 * @priv: drm_privacy_screen to attach3015 *3016 * Create and attach the standard privacy-screen properties and register3017 * a generic notifier for generating sysfs-connector-status-events3018 * on external changes to the privacy-screen status.3019 * This function takes ownership of the passed in drm_privacy_screen and will3020 * call drm_privacy_screen_put() on it when the connector is destroyed.3021 */3022void drm_connector_attach_privacy_screen_provider(3023	struct drm_connector *connector, struct drm_privacy_screen *priv)3024{3025	connector->privacy_screen = priv;3026	connector->privacy_screen_notifier.notifier_call =3027		drm_connector_privacy_screen_notifier;3028 3029	drm_connector_create_privacy_screen_properties(connector);3030	drm_connector_update_privacy_screen_properties(connector, true);3031	drm_connector_attach_privacy_screen_properties(connector);3032}3033EXPORT_SYMBOL(drm_connector_attach_privacy_screen_provider);3034 3035/**3036 * drm_connector_update_privacy_screen - update connector's privacy-screen sw-state3037 * @connector_state: connector-state to update the privacy-screen for3038 *3039 * This function calls drm_privacy_screen_set_sw_state() on the connector's3040 * privacy-screen.3041 *3042 * If the connector has no privacy-screen, then this is a no-op.3043 */3044void drm_connector_update_privacy_screen(const struct drm_connector_state *connector_state)3045{3046	struct drm_connector *connector = connector_state->connector;3047	int ret;3048 3049	if (!connector->privacy_screen)3050		return;3051 3052	ret = drm_privacy_screen_set_sw_state(connector->privacy_screen,3053					      connector_state->privacy_screen_sw_state);3054	if (ret) {3055		drm_err(connector->dev, "Error updating privacy-screen sw_state\n");3056		return;3057	}3058 3059	/* The hw_state property value may have changed, update it. */3060	drm_connector_update_privacy_screen_properties(connector, false);3061}3062EXPORT_SYMBOL(drm_connector_update_privacy_screen);3063 3064int drm_connector_set_obj_prop(struct drm_mode_object *obj,3065				    struct drm_property *property,3066				    uint64_t value)3067{3068	int ret = -EINVAL;3069	struct drm_connector *connector = obj_to_connector(obj);3070 3071	/* Do DPMS ourselves */3072	if (property == connector->dev->mode_config.dpms_property) {3073		ret = (*connector->funcs->dpms)(connector, (int)value);3074	} else if (connector->funcs->set_property)3075		ret = connector->funcs->set_property(connector, property, value);3076 3077	if (!ret)3078		drm_object_property_set_value(&connector->base, property, value);3079	return ret;3080}3081 3082int drm_connector_property_set_ioctl(struct drm_device *dev,3083				     void *data, struct drm_file *file_priv)3084{3085	struct drm_mode_connector_set_property *conn_set_prop = data;3086	struct drm_mode_obj_set_property obj_set_prop = {3087		.value = conn_set_prop->value,3088		.prop_id = conn_set_prop->prop_id,3089		.obj_id = conn_set_prop->connector_id,3090		.obj_type = DRM_MODE_OBJECT_CONNECTOR3091	};3092 3093	/* It does all the locking and checking we need */3094	return drm_mode_obj_set_property_ioctl(dev, &obj_set_prop, file_priv);3095}3096 3097static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)3098{3099	/* For atomic drivers only state objects are synchronously updated and3100	 * protected by modeset locks, so check those first.3101	 */3102	if (connector->state)3103		return connector->state->best_encoder;3104	return connector->encoder;3105}3106 3107static bool3108drm_mode_expose_to_userspace(const struct drm_display_mode *mode,3109			     const struct list_head *modes,3110			     const struct drm_file *file_priv)3111{3112	/*3113	 * If user-space hasn't configured the driver to expose the stereo 3D3114	 * modes, don't expose them.3115	 */3116	if (!file_priv->stereo_allowed && drm_mode_is_stereo(mode))3117		return false;3118	/*3119	 * If user-space hasn't configured the driver to expose the modes3120	 * with aspect-ratio, don't expose them. However if such a mode3121	 * is unique, let it be exposed, but reset the aspect-ratio flags3122	 * while preparing the list of user-modes.3123	 */3124	if (!file_priv->aspect_ratio_allowed) {3125		const struct drm_display_mode *mode_itr;3126 3127		list_for_each_entry(mode_itr, modes, head) {3128			if (mode_itr->expose_to_userspace &&3129			    drm_mode_match(mode_itr, mode,3130					   DRM_MODE_MATCH_TIMINGS |3131					   DRM_MODE_MATCH_CLOCK |3132					   DRM_MODE_MATCH_FLAGS |3133					   DRM_MODE_MATCH_3D_FLAGS))3134				return false;3135		}3136	}3137 3138	return true;3139}3140 3141int drm_mode_getconnector(struct drm_device *dev, void *data,3142			  struct drm_file *file_priv)3143{3144	struct drm_mode_get_connector *out_resp = data;3145	struct drm_connector *connector;3146	struct drm_encoder *encoder;3147	struct drm_display_mode *mode;3148	int mode_count = 0;3149	int encoders_count = 0;3150	int ret = 0;3151	int copied = 0;3152	struct drm_mode_modeinfo u_mode;3153	struct drm_mode_modeinfo __user *mode_ptr;3154	uint32_t __user *encoder_ptr;3155	bool is_current_master;3156 3157	if (!drm_core_check_feature(dev, DRIVER_MODESET))3158		return -EOPNOTSUPP;3159 3160	memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));3161 3162	connector = drm_connector_lookup(dev, file_priv, out_resp->connector_id);3163	if (!connector)3164		return -ENOENT;3165 3166	encoders_count = hweight32(connector->possible_encoders);3167 3168	if ((out_resp->count_encoders >= encoders_count) && encoders_count) {3169		copied = 0;3170		encoder_ptr = (uint32_t __user *)(unsigned long)(out_resp->encoders_ptr);3171 3172		drm_connector_for_each_possible_encoder(connector, encoder) {3173			if (put_user(encoder->base.id, encoder_ptr + copied)) {3174				ret = -EFAULT;3175				goto out;3176			}3177			copied++;3178		}3179	}3180	out_resp->count_encoders = encoders_count;3181 3182	out_resp->connector_id = connector->base.id;3183	out_resp->connector_type = connector->connector_type;3184	out_resp->connector_type_id = connector->connector_type_id;3185 3186	is_current_master = drm_is_current_master(file_priv);3187 3188	mutex_lock(&dev->mode_config.mutex);3189	if (out_resp->count_modes == 0) {3190		if (is_current_master)3191			connector->funcs->fill_modes(connector,3192						     dev->mode_config.max_width,3193						     dev->mode_config.max_height);3194		else3195			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\n",3196				    connector->base.id, connector->name);3197	}3198 3199	out_resp->mm_width = connector->display_info.width_mm;3200	out_resp->mm_height = connector->display_info.height_mm;3201	out_resp->subpixel = connector->display_info.subpixel_order;3202	out_resp->connection = connector->status;3203 3204	/* delayed so we get modes regardless of pre-fill_modes state */3205	list_for_each_entry(mode, &connector->modes, head) {3206		WARN_ON(mode->expose_to_userspace);3207 3208		if (drm_mode_expose_to_userspace(mode, &connector->modes,3209						 file_priv)) {3210			mode->expose_to_userspace = true;3211			mode_count++;3212		}3213	}3214 3215	/*3216	 * This ioctl is called twice, once to determine how much space is3217	 * needed, and the 2nd time to fill it.3218	 */3219	if ((out_resp->count_modes >= mode_count) && mode_count) {3220		copied = 0;3221		mode_ptr = (struct drm_mode_modeinfo __user *)(unsigned long)out_resp->modes_ptr;3222		list_for_each_entry(mode, &connector->modes, head) {3223			if (!mode->expose_to_userspace)3224				continue;3225 3226			/* Clear the tag for the next time around */3227			mode->expose_to_userspace = false;3228 3229			drm_mode_convert_to_umode(&u_mode, mode);3230			/*3231			 * Reset aspect ratio flags of user-mode, if modes with3232			 * aspect-ratio are not supported.3233			 */3234			if (!file_priv->aspect_ratio_allowed)3235				u_mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;3236			if (copy_to_user(mode_ptr + copied,3237					 &u_mode, sizeof(u_mode))) {3238				ret = -EFAULT;3239 3240				/*3241				 * Clear the tag for the rest of3242				 * the modes for the next time around.3243				 */3244				list_for_each_entry_continue(mode, &connector->modes, head)3245					mode->expose_to_userspace = false;3246 3247				mutex_unlock(&dev->mode_config.mutex);3248 3249				goto out;3250			}3251			copied++;3252		}3253	} else {3254		/* Clear the tag for the next time around */3255		list_for_each_entry(mode, &connector->modes, head)3256			mode->expose_to_userspace = false;3257	}3258 3259	out_resp->count_modes = mode_count;3260	mutex_unlock(&dev->mode_config.mutex);3261 3262	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);3263	encoder = drm_connector_get_encoder(connector);3264	if (encoder)3265		out_resp->encoder_id = encoder->base.id;3266	else3267		out_resp->encoder_id = 0;3268 3269	/* Only grab properties after probing, to make sure EDID and other3270	 * properties reflect the latest status.3271	 */3272	ret = drm_mode_object_get_properties(&connector->base, file_priv->atomic,3273			(uint32_t __user *)(unsigned long)(out_resp->props_ptr),3274			(uint64_t __user *)(unsigned long)(out_resp->prop_values_ptr),3275			&out_resp->count_props);3276	drm_modeset_unlock(&dev->mode_config.connection_mutex);3277 3278out:3279	drm_connector_put(connector);3280 3281	return ret;3282}3283 3284/**3285 * drm_connector_find_by_fwnode - Find a connector based on the associated fwnode3286 * @fwnode: fwnode for which to find the matching drm_connector3287 *3288 * This functions looks up a drm_connector based on its associated fwnode. When3289 * a connector is found a reference to the connector is returned. The caller must3290 * call drm_connector_put() to release this reference when it is done with the3291 * connector.3292 *3293 * Returns: A reference to the found connector or an ERR_PTR().3294 */3295struct drm_connector *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)3296{3297	struct drm_connector *connector, *found = ERR_PTR(-ENODEV);3298 3299	if (!fwnode)3300		return ERR_PTR(-ENODEV);3301 3302	mutex_lock(&connector_list_lock);3303 3304	list_for_each_entry(connector, &connector_list, global_connector_list_entry) {3305		if (connector->fwnode == fwnode ||3306		    (connector->fwnode && connector->fwnode->secondary == fwnode)) {3307			drm_connector_get(connector);3308			found = connector;3309			break;3310		}3311	}3312 3313	mutex_unlock(&connector_list_lock);3314 3315	return found;3316}3317 3318/**3319 * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to connector3320 * @connector_fwnode: fwnode_handle to report the event on3321 * @status: hot plug detect logical state3322 *3323 * On some hardware a hotplug event notification may come from outside the display3324 * driver / device. An example of this is some USB Type-C setups where the hardware3325 * muxes the DisplayPort data and aux-lines but does not pass the altmode HPD3326 * status bit to the GPU's DP HPD pin.3327 *3328 * This function can be used to report these out-of-band events after obtaining3329 * a drm_connector reference through calling drm_connector_find_by_fwnode().3330 */3331void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,3332				     enum drm_connector_status status)3333{3334	struct drm_connector *connector;3335 3336	connector = drm_connector_find_by_fwnode(connector_fwnode);3337	if (IS_ERR(connector))3338		return;3339 3340	if (connector->funcs->oob_hotplug_event)3341		connector->funcs->oob_hotplug_event(connector, status);3342 3343	drm_connector_put(connector);3344}3345EXPORT_SYMBOL(drm_connector_oob_hotplug_event);3346 3347 3348/**3349 * DOC: Tile group3350 *3351 * Tile groups are used to represent tiled monitors with a unique integer3352 * identifier. Tiled monitors using DisplayID v1.3 have a unique 8-byte handle,3353 * we store this in a tile group, so we have a common identifier for all tiles3354 * in a monitor group. The property is called "TILE". Drivers can manage tile3355 * groups using drm_mode_create_tile_group(), drm_mode_put_tile_group() and3356 * drm_mode_get_tile_group(). But this is only needed for internal panels where3357 * the tile group information is exposed through a non-standard way.3358 */3359 3360static void drm_tile_group_free(struct kref *kref)3361{3362	struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);3363	struct drm_device *dev = tg->dev;3364 3365	mutex_lock(&dev->mode_config.idr_mutex);3366	idr_remove(&dev->mode_config.tile_idr, tg->id);3367	mutex_unlock(&dev->mode_config.idr_mutex);3368	kfree(tg);3369}3370 3371/**3372 * drm_mode_put_tile_group - drop a reference to a tile group.3373 * @dev: DRM device3374 * @tg: tile group to drop reference to.3375 *3376 * drop reference to tile group and free if 0.3377 */3378void drm_mode_put_tile_group(struct drm_device *dev,3379			     struct drm_tile_group *tg)3380{3381	kref_put(&tg->refcount, drm_tile_group_free);3382}3383EXPORT_SYMBOL(drm_mode_put_tile_group);3384 3385/**3386 * drm_mode_get_tile_group - get a reference to an existing tile group3387 * @dev: DRM device3388 * @topology: 8-bytes unique per monitor.3389 *3390 * Use the unique bytes to get a reference to an existing tile group.3391 *3392 * RETURNS:3393 * tile group or NULL if not found.3394 */3395struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,3396					       const char topology[8])3397{3398	struct drm_tile_group *tg;3399	int id;3400 3401	mutex_lock(&dev->mode_config.idr_mutex);3402	idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {3403		if (!memcmp(tg->group_data, topology, 8)) {3404			if (!kref_get_unless_zero(&tg->refcount))3405				tg = NULL;3406			mutex_unlock(&dev->mode_config.idr_mutex);3407			return tg;3408		}3409	}3410	mutex_unlock(&dev->mode_config.idr_mutex);3411	return NULL;3412}3413EXPORT_SYMBOL(drm_mode_get_tile_group);3414 3415/**3416 * drm_mode_create_tile_group - create a tile group from a displayid description3417 * @dev: DRM device3418 * @topology: 8-bytes unique per monitor.3419 *3420 * Create a tile group for the unique monitor, and get a unique3421 * identifier for the tile group.3422 *3423 * RETURNS:3424 * new tile group or NULL.3425 */3426struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,3427						  const char topology[8])3428{3429	struct drm_tile_group *tg;3430	int ret;3431 3432	tg = kzalloc(sizeof(*tg), GFP_KERNEL);3433	if (!tg)3434		return NULL;3435 3436	kref_init(&tg->refcount);3437	memcpy(tg->group_data, topology, 8);3438	tg->dev = dev;3439 3440	mutex_lock(&dev->mode_config.idr_mutex);3441	ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);3442	if (ret >= 0) {3443		tg->id = ret;3444	} else {3445		kfree(tg);3446		tg = NULL;3447	}3448 3449	mutex_unlock(&dev->mode_config.idr_mutex);3450	return tg;3451}3452EXPORT_SYMBOL(drm_mode_create_tile_group);3453