1820 lines · 60.0 KB · C
RawDownload
/* * Copyright (c) 2014 Samsung Electronics Co., Ltd * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sub license, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include <linux/debugfs.h>#include <linux/err.h>#include <linux/export.h>#include <linux/media-bus-format.h>#include <linux/module.h>#include <linux/mutex.h>#include <linux/srcu.h> #include <drm/drm_atomic_state_helper.h>#include <drm/drm_bridge.h>#include <drm/drm_debugfs.h>#include <drm/drm_edid.h>#include <drm/drm_encoder.h>#include <drm/drm_file.h>#include <drm/drm_of.h>#include <drm/drm_print.h> #include "drm_crtc_internal.h" /** * DOC: overview * * &struct drm_bridge represents a device that hangs on to an encoder. These are * handy when a regular &drm_encoder entity isn't enough to represent the entire * encoder chain. * * A bridge is always attached to a single &drm_encoder at a time, but can be * either connected to it directly, or through a chain of bridges:: * *     [ CRTC ---> ] Encoder ---> Bridge A ---> Bridge B * * Here, the output of the encoder feeds to bridge A, and that furthers feeds to * bridge B. Bridge chains can be arbitrarily long, and shall be fully linear: * Chaining multiple bridges to the output of a bridge, or the same bridge to * the output of different bridges, is not supported. * * &drm_bridge, like &drm_panel, aren't &drm_mode_object entities like planes, * CRTCs, encoders or connectors and hence are not visible to userspace. They * just provide additional hooks to get the desired output at the end of the * encoder chain. */ /** * DOC:	display driver integration * * Display drivers are responsible for linking encoders with the first bridge * in the chains. This is done by acquiring the appropriate bridge with * devm_drm_of_get_bridge(). Once acquired, the bridge shall be attached to the * encoder with a call to drm_bridge_attach(). * * Bridges are responsible for linking themselves with the next bridge in the * chain, if any. This is done the same way as for encoders, with the call to * drm_bridge_attach() occurring in the &drm_bridge_funcs.attach operation. * * Once these links are created, the bridges can participate along with encoder * functions to perform mode validation and fixup (through * drm_bridge_chain_mode_valid() and drm_atomic_bridge_chain_check()), mode * setting (through drm_bridge_chain_mode_set()), enable (through * drm_atomic_bridge_chain_pre_enable() and drm_atomic_bridge_chain_enable()) * and disable (through drm_atomic_bridge_chain_disable() and * drm_atomic_bridge_chain_post_disable()). Those functions call the * corresponding operations provided in &drm_bridge_funcs in sequence for all * bridges in the chain. * * For display drivers that use the atomic helpers * drm_atomic_helper_check_modeset(), * drm_atomic_helper_commit_modeset_enables() and * drm_atomic_helper_commit_modeset_disables() (either directly in hand-rolled * commit check and commit tail handlers, or through the higher-level * drm_atomic_helper_check() and drm_atomic_helper_commit_tail() or * drm_atomic_helper_commit_tail_rpm() helpers), this is done transparently and * requires no intervention from the driver. For other drivers, the relevant * DRM bridge chain functions shall be called manually. * * Bridges also participate in implementing the &drm_connector at the end of * the bridge chain. Display drivers may use the drm_bridge_connector_init() * helper to create the &drm_connector, or implement it manually on top of the * connector-related operations exposed by the bridge (see the overview * documentation of bridge operations for more details). */ /** * DOC: special care dsi * * The interaction between the bridges and other frameworks involved in * the probing of the upstream driver and the bridge driver can be * challenging. Indeed, there's multiple cases that needs to be * considered: * * - The upstream driver doesn't use the component framework and isn't a *   MIPI-DSI host. In this case, the bridge driver will probe at some *   point and the upstream driver should try to probe again by returning *   EPROBE_DEFER as long as the bridge driver hasn't probed. * * - The upstream driver doesn't use the component framework, but is a *   MIPI-DSI host. The bridge device uses the MIPI-DCS commands to be *   controlled. In this case, the bridge device is a child of the *   display device and when it will probe it's assured that the display *   device (and MIPI-DSI host) is present. The upstream driver will be *   assured that the bridge driver is connected between the *   &mipi_dsi_host_ops.attach and &mipi_dsi_host_ops.detach operations. *   Therefore, it must run mipi_dsi_host_register() in its probe *   function, and then run drm_bridge_attach() in its *   &mipi_dsi_host_ops.attach hook. * * - The upstream driver uses the component framework and is a MIPI-DSI *   host. The bridge device uses the MIPI-DCS commands to be *   controlled. This is the same situation than above, and can run *   mipi_dsi_host_register() in either its probe or bind hooks. * * - The upstream driver uses the component framework and is a MIPI-DSI *   host. The bridge device uses a separate bus (such as I2C) to be *   controlled. In this case, there's no correlation between the probe *   of the bridge and upstream drivers, so care must be taken to avoid *   an endless EPROBE_DEFER loop, with each driver waiting for the *   other to probe. * * The ideal pattern to cover the last item (and all the others in the * MIPI-DSI host driver case) is to split the operations like this: * * - The MIPI-DSI host driver must run mipi_dsi_host_register() in its *   probe hook. It will make sure that the MIPI-DSI host sticks around, *   and that the driver's bind can be called. * * - In its probe hook, the bridge driver must try to find its MIPI-DSI *   host, register as a MIPI-DSI device and attach the MIPI-DSI device *   to its host. The bridge driver is now functional. * * - In its &struct mipi_dsi_host_ops.attach hook, the MIPI-DSI host can *   now add its component. Its bind hook will now be called and since *   the bridge driver is attached and registered, we can now look for *   and attach it. * * At this point, we're now certain that both the upstream driver and * the bridge driver are functional and we can't have a deadlock-like * situation when probing. */ /** * DOC: dsi bridge operations * * DSI host interfaces are expected to be implemented as bridges rather than * encoders, however there are a few aspects of their operation that need to * be defined in order to provide a consistent interface. * * A DSI host should keep the PHY powered down until the pre_enable operation is * called. All lanes are in an undefined idle state up to this point, and it * must not be assumed that it is LP-11. * pre_enable should initialise the PHY, set the data lanes to LP-11, and the * clock lane to either LP-11 or HS depending on the mode_flag * %MIPI_DSI_CLOCK_NON_CONTINUOUS. * * Ordinarily the downstream bridge DSI peripheral pre_enable will have been * called before the DSI host. If the DSI peripheral requires LP-11 and/or * the clock lane to be in HS mode prior to pre_enable, then it can set the * &pre_enable_prev_first flag to request the pre_enable (and * post_disable) order to be altered to enable the DSI host first. * * Either the CRTC being enabled, or the DSI host enable operation should switch * the host to actively transmitting video on the data lanes. * * The reverse also applies. The DSI host disable operation or stopping the CRTC * should stop transmitting video, and the data lanes should return to the LP-11 * state. The DSI host &post_disable operation should disable the PHY. * If the &pre_enable_prev_first flag is set, then the DSI peripheral's * bridge &post_disable will be called before the DSI host's post_disable. * * Whilst it is valid to call &host_transfer prior to pre_enable or after * post_disable, the exact state of the lanes is undefined at this point. The * DSI host should initialise the interface, transmit the data, and then disable * the interface again. * * Ultra Low Power State (ULPS) is not explicitly supported by DRM. If * implemented, it therefore needs to be handled entirely within the DSI Host * driver. */ /** * DOC: bridge chain format selection * * A bridge chain, from display output processor to connector, may contain * bridges capable of converting between bus formats on their inputs, and * output formats on their outputs. For example, a bridge may be able to convert * from RGB to YCbCr 4:4:4, and pass through YCbCr 4:2:0 as-is, but not convert * from RGB to YCbCr 4:2:0. This means not all input formats map to all output * formats. * * Further adding to this, a desired output color format, as specified with the * "color format" DRM property, might not correspond 1:1 to what the display * driver should set at its output. The bridge chain it feeds into may only be * able to reach the desired output format, if a conversion from a different * starting format is performed. * * To deal with this complexity, the recursive bridge chain bus format selection * logic starts with the last bridge in the chain, usually the connector, and * then recursively walks the chain of bridges backwards to the first bridge, * trying to find a path. * * For a display driver to work in such a scenario, it should read the first * bridge's bridge state to figure out which bus format the chain resolved to. * If the first bridge's input format resolved to %MEDIA_BUS_FMT_FIXED, then its * output format should be used. * * Special handling is done for HDMI as it relates to format selection. Instead * of directly using the "color format" DRM property for bridge chains that end * in HDMI bridges, the bridge chain format selection logic will trust the logic * that set the HDMI output format. For the common HDMI state helper * functionality, this means that %DRM_CONNECTOR_COLOR_FORMAT_AUTO will allow * fallbacks to YCBCr 4:2:0 if the bandwidth requirements would otherwise be too * high but the mode and connector allow it. * * For bridge chains that do not end in an HDMI bridge, * %DRM_CONNECTOR_COLOR_FORMAT_AUTO will be satisfied with the first output * format on the last bridge for which it can find a path back to the first * bridge. */ /* Protect bridge_list and bridge_lingering_list */static DEFINE_MUTEX(bridge_lock);static LIST_HEAD(bridge_list);static LIST_HEAD(bridge_lingering_list); DEFINE_STATIC_SRCU(drm_bridge_unplug_srcu); /** * drm_bridge_enter - Enter DRM bridge critical section * @bridge: DRM bridge * @idx: Pointer to index that will be passed to the matching drm_bridge_exit() * * This function marks and protects the beginning of a section that should not * be entered after the bridge has been unplugged. The section end is marked * with drm_bridge_exit(). Calls to this function can be nested. * * Returns: * True if it is OK to enter the section, false otherwise. */bool drm_bridge_enter(struct drm_bridge *bridge, int *idx){	*idx = srcu_read_lock(&drm_bridge_unplug_srcu); 	if (bridge->unplugged) {		srcu_read_unlock(&drm_bridge_unplug_srcu, *idx);		return false;	} 	return true;}EXPORT_SYMBOL(drm_bridge_enter); /** * drm_bridge_exit - Exit DRM bridge critical section * @idx: index returned by drm_bridge_enter() * * This function marks the end of a section that should not be entered after * the bridge has been unplugged. */void drm_bridge_exit(int idx){	srcu_read_unlock(&drm_bridge_unplug_srcu, idx);}EXPORT_SYMBOL(drm_bridge_exit); /** * drm_bridge_unplug - declare a DRM bridge was unplugged and remove it * @bridge: DRM bridge * * This tells the bridge has been physically unplugged and no operations on * device resources must be done anymore. Entry-points can use * drm_bridge_enter() and drm_bridge_exit() to protect device resources in * a race free manner. * * Also unregisters the bridge. */void drm_bridge_unplug(struct drm_bridge *bridge){	bridge->unplugged = true; 	synchronize_srcu(&drm_bridge_unplug_srcu); 	drm_bridge_remove(bridge);}EXPORT_SYMBOL(drm_bridge_unplug); static void __drm_bridge_free(struct kref *kref){	struct drm_bridge *bridge = container_of(kref, struct drm_bridge, refcount); 	mutex_lock(&bridge_lock);	list_del(&bridge->list);	mutex_unlock(&bridge_lock); 	if (bridge->funcs->destroy)		bridge->funcs->destroy(bridge); 	drm_bridge_put(bridge->next_bridge); 	kfree(bridge->container);} /** * drm_bridge_get - Acquire a bridge reference * @bridge: DRM bridge; if NULL this function does nothing * * This function increments the bridge's refcount. * * Returns: * Pointer to @bridge. */struct drm_bridge *drm_bridge_get(struct drm_bridge *bridge){	if (bridge)		kref_get(&bridge->refcount); 	return bridge;}EXPORT_SYMBOL(drm_bridge_get); /** * drm_bridge_put - Release a bridge reference * @bridge: DRM bridge; if NULL or an ERR_PTR this function does nothing * * This function decrements the bridge's reference count and frees the * object if the reference count drops to zero. * * See also drm_bridge_clear_and_put() if you also need to set the pointer * to NULL */void drm_bridge_put(struct drm_bridge *bridge){	if (!IS_ERR_OR_NULL(bridge))		kref_put(&bridge->refcount, __drm_bridge_free);}EXPORT_SYMBOL(drm_bridge_put); /** * drm_bridge_clear_and_put - Given a bridge pointer, clear the pointer *                            then put the bridge * @bridge_pp: pointer to pointer to a struct drm_bridge; ``bridge_pp`` *             must be non-NULL; if ``*bridge_pp`` is NULL this function *             does nothing * * Helper to put a DRM bridge, but only after setting its pointer to * NULL. Useful when a struct drm_bridge reference must be dropped without * leaving a use-after-free window where the pointed bridge might have been * freed while still holding a pointer to it. * * For struct ``drm_bridge *some_bridge``, this code:: * *     drm_bridge_clear_and_put(&some_bridge); * * is equivalent to the more complex:: * *     struct drm_bridge *temp = some_bridge; *     some_bridge = NULL; *     drm_bridge_put(temp); */void drm_bridge_clear_and_put(struct drm_bridge **bridge_pp){	struct drm_bridge *bridge = *bridge_pp; 	*bridge_pp = NULL;	drm_bridge_put(bridge);}EXPORT_SYMBOL(drm_bridge_clear_and_put); /** * drm_bridge_put_void - wrapper to drm_bridge_put() taking a void pointer * * @data: pointer to @struct drm_bridge, cast to a void pointer * * Wrapper of drm_bridge_put() to be used when a function taking a void * pointer is needed, for example as a devm action. */static void drm_bridge_put_void(void *data){	struct drm_bridge *bridge = (struct drm_bridge *)data; 	drm_bridge_put(bridge);} void *__devm_drm_bridge_alloc(struct device *dev, size_t size, size_t offset,			      const struct drm_bridge_funcs *funcs){	void *container;	struct drm_bridge *bridge;	int err; 	if (!funcs) {		dev_warn(dev, "Missing funcs pointer\n");		return ERR_PTR(-EINVAL);	} 	container = kzalloc(size, GFP_KERNEL);	if (!container)		return ERR_PTR(-ENOMEM); 	bridge = container + offset;	INIT_LIST_HEAD(&bridge->list);	bridge->container = container;	bridge->funcs = funcs;	kref_init(&bridge->refcount); 	err = devm_add_action_or_reset(dev, drm_bridge_put_void, bridge);	if (err)		return ERR_PTR(err); 	return container;}EXPORT_SYMBOL(__devm_drm_bridge_alloc); /** * drm_bridge_add - register a bridge * * @bridge: bridge control structure * * Add the given bridge to the global list of bridges, where they can be * found by users via of_drm_find_and_get_bridge(). * * The bridge to be added must have been allocated by * devm_drm_bridge_alloc(). */void drm_bridge_add(struct drm_bridge *bridge){	if (!bridge->container)		DRM_WARN("DRM bridge corrupted or not allocated by devm_drm_bridge_alloc()\n"); 	drm_bridge_get(bridge); 	/*	 * If the bridge was previously added and then removed, it is now	 * in bridge_lingering_list. Remove it or bridge_lingering_list will be	 * corrupted when adding this bridge to bridge_list below.	 */	if (!list_empty(&bridge->list))		list_del_init(&bridge->list); 	mutex_init(&bridge->hpd_state_mutex);	mutex_init(&bridge->hpd_mutex); 	if (bridge->ops & DRM_BRIDGE_OP_HDMI)		bridge->ycbcr_420_allowed = !!(bridge->supported_formats &					       BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420)); 	mutex_lock(&bridge_lock);	list_add_tail(&bridge->list, &bridge_list);	mutex_unlock(&bridge_lock);}EXPORT_SYMBOL(drm_bridge_add); static void drm_bridge_remove_void(void *bridge){	drm_bridge_remove(bridge);} /** * devm_drm_bridge_add - devm managed version of drm_bridge_add() * * @dev: device to tie the bridge lifetime to * @bridge: bridge control structure * * This is the managed version of drm_bridge_add() which automatically * calls drm_bridge_remove() when @dev is unbound. * * Return: 0 if no error or negative error code. */int devm_drm_bridge_add(struct device *dev, struct drm_bridge *bridge){	drm_bridge_add(bridge);	return devm_add_action_or_reset(dev, drm_bridge_remove_void, bridge);}EXPORT_SYMBOL(devm_drm_bridge_add); /** * drm_bridge_remove - unregister a bridge * * @bridge: bridge control structure *

Lines 1–500 of 1820.