/*
 * 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
 *
 * Remove the given bridge from the global list of registered bridges, so
 * it won't be found by users via of_drm_find_and_get_bridge(), and add it
 * to the lingering bridge list, to keep track of it until its allocated
 * memory is eventually freed.
 */
void drm_bridge_remove(struct drm_bridge *bridge)
{
	mutex_lock(&bridge_lock);
	list_move_tail(&bridge->list, &bridge_lingering_list);
	mutex_unlock(&bridge_lock);

	mutex_destroy(&bridge->hpd_mutex);
	mutex_destroy(&bridge->hpd_state_mutex);

	drm_bridge_put(bridge);
}
EXPORT_SYMBOL(drm_bridge_remove);

static struct drm_private_state *
drm_bridge_atomic_duplicate_priv_state(struct drm_private_obj *obj)
{
	struct drm_bridge *bridge = drm_priv_to_bridge(obj);
	struct drm_bridge_state *state;

	state = bridge->funcs->atomic_duplicate_state(bridge);
	return state ? &state->base : NULL;
}

static void
drm_bridge_atomic_destroy_priv_state(struct drm_private_obj *obj,
				     struct drm_private_state *s)
{
	struct drm_bridge_state *state = drm_priv_to_bridge_state(s);
	struct drm_bridge *bridge = drm_priv_to_bridge(obj);

	bridge->funcs->atomic_destroy_state(bridge, state);
}

static struct drm_private_state *
drm_bridge_atomic_create_priv_state(struct drm_private_obj *obj)
{
	struct drm_bridge *bridge = drm_priv_to_bridge(obj);
	struct drm_bridge_state *state;

	state = bridge->funcs->atomic_create_state(bridge);
	if (IS_ERR(state))
		return ERR_CAST(state);

	return &state->base;
}

static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = {
	.atomic_create_state = drm_bridge_atomic_create_priv_state,
	.atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state,
	.atomic_destroy_state = drm_bridge_atomic_destroy_priv_state,
};

/**
 * drm_bridge_attach - attach the bridge to an encoder's chain
 *
 * @encoder: DRM encoder
 * @bridge: bridge to attach
 * @previous: previous bridge in the chain (optional)
 * @flags: DRM_BRIDGE_ATTACH_* flags
 *
 * Called by a kms driver to link the bridge to an encoder's chain. The previous
 * argument specifies the previous bridge in the chain. If NULL, the bridge is
 * linked directly at the encoder's output. Otherwise it is linked at the
 * previous bridge's output.
 *
 * If non-NULL the previous bridge must be already attached by a call to this
 * function.
 *
 * The bridge to be attached must have been previously added by
 * drm_bridge_add().
 *
 * Note that bridges attached to encoders are auto-detached during encoder
 * cleanup in drm_encoder_cleanup(), so drm_bridge_attach() should generally
 * *not* be balanced with a drm_bridge_detach() in driver code.
 *
 * RETURNS:
 * Zero on success, error code on failure
 */
int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
		      struct drm_bridge *previous,
		      enum drm_bridge_attach_flags flags)
{
	int ret;

	if (!encoder || !bridge)
		return -EINVAL;

	if (!bridge->container)
		DRM_WARN("DRM bridge corrupted or not allocated by devm_drm_bridge_alloc()\n");

	if (list_empty(&bridge->list))
		DRM_WARN("Missing drm_bridge_add() before attach\n");

	drm_bridge_get(bridge);

	if (previous && (!previous->dev || previous->encoder != encoder)) {
		ret = -EINVAL;
		goto err_put_bridge;
	}

	if (bridge->dev) {
		ret = -EBUSY;
		goto err_put_bridge;
	}

	bridge->dev = encoder->dev;
	bridge->encoder = encoder;

	mutex_lock(&encoder->bridge_chain_mutex);
	if (previous)
		list_add(&bridge->chain_node, &previous->chain_node);
	else
		list_add(&bridge->chain_node, &encoder->bridge_chain);
	mutex_unlock(&encoder->bridge_chain_mutex);

	if (bridge->funcs->attach) {
		ret = bridge->funcs->attach(bridge, encoder, flags);
		if (ret < 0)
			goto err_reset_bridge;
	}

	drm_atomic_private_obj_init(bridge->dev, &bridge->base,
				    &drm_bridge_priv_state_funcs);

	return 0;

err_reset_bridge:
	bridge->dev = NULL;
	bridge->encoder = NULL;
	mutex_lock(&encoder->bridge_chain_mutex);
	list_del(&bridge->chain_node);
	mutex_unlock(&encoder->bridge_chain_mutex);

	if (ret != -EPROBE_DEFER)
		DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n",
			  bridge->of_node, encoder->name, ret);
	else
		dev_err_probe(encoder->dev->dev, -EPROBE_DEFER,
			      "failed to attach bridge %pOF to encoder %s\n",
			      bridge->of_node, encoder->name);

err_put_bridge:
	drm_bridge_put(bridge);
	return ret;
}
EXPORT_SYMBOL(drm_bridge_attach);

void drm_bridge_detach(struct drm_bridge *bridge)
{
	if (WARN_ON(!bridge))
		return;

	if (WARN_ON(!bridge->dev))
		return;

	drm_atomic_private_obj_fini(&bridge->base);

	if (bridge->funcs->detach)
		bridge->funcs->detach(bridge);

	list_del(&bridge->chain_node);
	bridge->dev = NULL;
	drm_bridge_put(bridge);
}

/**
 * DOC: bridge operations
 *
 * Bridge drivers expose operations through the &drm_bridge_funcs structure.
 * The DRM internals (atomic and CRTC helpers) use the helpers defined in
 * drm_bridge.c to call bridge operations. Those operations are divided in
 * three big categories to support different parts of the bridge usage.
 *
 * - The encoder-related operations support control of the bridges in the
 *   chain, and are roughly counterparts to the &drm_encoder_helper_funcs
 *   operations. They are used by the legacy CRTC and the atomic modeset
 *   helpers to perform mode validation, fixup and setting, and enable and
 *   disable the bridge automatically.
 *
 *   The enable and disable operations are split in
 *   &drm_bridge_funcs.atomic_pre_enable, &drm_bridge_funcs.atomic_enable,
 *   &drm_bridge_funcs.atomic_disable and &drm_bridge_funcs.atomic_post_disable
 *   to provide finer-grained control.
 *
 *   Bridge drivers may implement the legacy version of those operations, or
 *   the atomic version (prefixed with atomic\_), in which case they shall also
 *   implement the atomic state bookkeeping operations
 *   (&drm_bridge_funcs.atomic_duplicate_state,
 *   &drm_bridge_funcs.atomic_destroy_state and &drm_bridge_funcs.reset).
 *   Mixing atomic and non-atomic versions of the operations is not supported.
 *
 * - The bus format negotiation operations
 *   &drm_bridge_funcs.atomic_get_output_bus_fmts and
 *   &drm_bridge_funcs.atomic_get_input_bus_fmts allow bridge drivers to
 *   negotiate the formats transmitted between bridges in the chain when
 *   multiple formats are supported. Negotiation for formats is performed
 *   transparently for display drivers by the atomic modeset helpers. Only
 *   atomic versions of those operations exist, bridge drivers that need to
 *   implement them shall thus also implement the atomic version of the
 *   encoder-related operations. This feature is not supported by the legacy
 *   CRTC helpers.
 *
 * - The connector-related operations support implementing a &drm_connector
 *   based on a chain of bridges. DRM bridges traditionally create a
 *   &drm_connector for bridges meant to be used at the end of the chain. This
 *   puts additional burden on bridge drivers, especially for bridges that may
 *   be used in the middle of a chain or at the end of it. Furthermore, it
 *   requires all operations of the &drm_connector to be handled by a single
 *   bridge, which doesn't always match the hardware architecture.
 *
 *   To simplify bridge drivers and make the connector implementation more
 *   flexible, a new model allows bridges to unconditionally skip creation of
 *   &drm_connector and instead expose &drm_bridge_funcs operations to support
 *   an externally-implemented &drm_connector. Those operations are
 *   &drm_bridge_funcs.detect, &drm_bridge_funcs.get_modes,
 *   &drm_bridge_funcs.get_edid, &drm_bridge_funcs.hpd_notify,
 *   &drm_bridge_funcs.hpd_enable and &drm_bridge_funcs.hpd_disable. When
 *   implemented, display drivers shall create a &drm_connector instance for
 *   each chain of bridges, and implement those connector instances based on
 *   the bridge connector operations.
 *
 *   Bridge drivers shall implement the connector-related operations for all
 *   the features that the bridge hardware support. For instance, if a bridge
 *   supports reading EDID, the &drm_bridge_funcs.get_edid shall be
 *   implemented. This however doesn't mean that the DDC lines are wired to the
 *   bridge on a particular platform, as they could also be connected to an I2C
 *   controller of the SoC. Support for the connector-related operations on the
 *   running platform is reported through the &drm_bridge.ops flags. Bridge
 *   drivers shall detect which operations they can support on the platform
 *   (usually this information is provided by ACPI or DT), and set the
 *   &drm_bridge.ops flags for all supported operations. A flag shall only be
 *   set if the corresponding &drm_bridge_funcs operation is implemented, but
 *   an implemented operation doesn't necessarily imply that the corresponding
 *   flag will be set. Display drivers shall use the &drm_bridge.ops flags to
 *   decide which bridge to delegate a connector operation to. This mechanism
 *   allows providing a single static const &drm_bridge_funcs instance in
 *   bridge drivers, improving security by storing function pointers in
 *   read-only memory.
 *
 *   In order to ease transition, bridge drivers may support both the old and
 *   new models by making connector creation optional and implementing the
 *   connected-related bridge operations. Connector creation is then controlled
 *   by the flags argument to the drm_bridge_attach() function. Display drivers
 *   that support the new model and create connectors themselves shall set the
 *   %DRM_BRIDGE_ATTACH_NO_CONNECTOR flag, and bridge drivers shall then skip
 *   connector creation. For intermediate bridges in the chain, the flag shall
 *   be passed to the drm_bridge_attach() call for the downstream bridge.
 *   Bridge drivers that implement the new model only shall return an error
 *   from their &drm_bridge_funcs.attach handler when the
 *   %DRM_BRIDGE_ATTACH_NO_CONNECTOR flag is not set. New display drivers
 *   should use the new model, and convert the bridge drivers they use if
 *   needed, in order to gradually transition to the new model.
 */

/**
 * drm_bridge_chain_mode_valid - validate the mode against all bridges in the
 *				 encoder chain.
 * @first_bridge: bridge control structure
 * @info: display info against which the mode shall be validated
 * @mode: desired mode to be validated
 *
 * Calls &drm_bridge_funcs.mode_valid for all the bridges in the encoder
 * chain, starting from the first bridge to the last. If at least one bridge
 * does not accept the mode the function returns the error code.
 *
 * Note: the bridge passed should be the one closest to the encoder.
 *
 * RETURNS:
 * MODE_OK on success, drm_mode_status Enum error code on failure
 */
enum drm_mode_status
drm_bridge_chain_mode_valid(struct drm_bridge *first_bridge,
			    const struct drm_display_info *info,
			    const struct drm_display_mode *mode)
{
	if (!first_bridge)
		return MODE_OK;

	drm_for_each_bridge_in_chain_from(first_bridge, bridge) {
		enum drm_mode_status ret;

		if (!bridge->funcs->mode_valid)
			continue;

		ret = bridge->funcs->mode_valid(bridge, info, mode);
		if (ret != MODE_OK)
			return ret;
	}

	return MODE_OK;
}
EXPORT_SYMBOL(drm_bridge_chain_mode_valid);

/**
 * drm_bridge_chain_mode_set - set proposed mode for all bridges in the
 *			       encoder chain
 * @first_bridge: bridge control structure
 * @mode: desired mode to be set for the encoder chain
 * @adjusted_mode: updated mode that works for this encoder chain
 *
 * Calls &drm_bridge_funcs.mode_set op for all the bridges in the
 * encoder chain, starting from the first bridge to the last.
 *
 * Note: the bridge passed should be the one closest to the encoder
 */
void drm_bridge_chain_mode_set(struct drm_bridge *first_bridge,
			       const struct drm_display_mode *mode,
			       const struct drm_display_mode *adjusted_mode)
{
	if (!first_bridge)
		return;

	drm_for_each_bridge_in_chain_from(first_bridge, bridge)
		if (bridge->funcs->mode_set)
			bridge->funcs->mode_set(bridge, mode, adjusted_mode);
}
EXPORT_SYMBOL(drm_bridge_chain_mode_set);

/**
 * drm_atomic_bridge_chain_disable - disables all bridges in the encoder chain
 * @bridge: bridge control structure
 * @state: atomic state being committed
 *
 * Calls &drm_bridge_funcs.atomic_disable op for all the bridges in the encoder
 * chain, starting from the last bridge to the first. These are called before
 * calling &drm_encoder_helper_funcs.atomic_disable
 *
 * Note: the bridge passed should be the one closest to the encoder
 */
void drm_atomic_bridge_chain_disable(struct drm_bridge *bridge,
				     struct drm_atomic_commit *state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *iter;

	if (!bridge)
		return;

	encoder = bridge->encoder;
	mutex_lock(&encoder->bridge_chain_mutex);
	list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
		if (iter->funcs->atomic_disable)
			iter->funcs->atomic_disable(iter, state);

		if (iter == bridge)
			break;
	}
	mutex_unlock(&encoder->bridge_chain_mutex);
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);

static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge,
						struct drm_atomic_commit *state)
{
	if (state && bridge->funcs->atomic_post_disable)
		bridge->funcs->atomic_post_disable(bridge, state);
}

/**
 * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
 *					  in the encoder chain
 * @bridge: bridge control structure
 * @state: atomic state being committed
 *
 * Calls &drm_bridge_funcs.atomic_post_disable op for all the bridges in the
 * encoder chain, starting from the first bridge to the last. These are called
 * after completing &drm_encoder_helper_funcs.atomic_disable
 *
 * If a bridge sets @pre_enable_prev_first, then the @post_disable for that
 * bridge will be called before the previous one to reverse the @pre_enable
 * calling direction.
 *
 * Example:
 * Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E
 *
 * With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting
 * @post_disable order would be,
 * Bridge B, Bridge A, Bridge E, Bridge D, Bridge C.
 *
 * Note: the bridge passed should be the one closest to the encoder
 */
void drm_atomic_bridge_chain_post_disable(struct drm_bridge *bridge,
					  struct drm_atomic_commit *state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *next, *limit;

	if (!bridge)
		return;

	encoder = bridge->encoder;

	mutex_lock(&encoder->bridge_chain_mutex);
	list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
		limit = NULL;

		if (!list_is_last(&bridge->chain_node, &encoder->bridge_chain)) {
			next = list_next_entry(bridge, chain_node);

			if (next->pre_enable_prev_first) {
				/* next bridge had requested that prev
				 * was enabled first, so disabled last
				 */
				limit = next;

				/* Find the next bridge that has NOT requested
				 * prev to be enabled first / disabled last
				 */
				list_for_each_entry_from(next, &encoder->bridge_chain,
							 chain_node) {
					if (!next->pre_enable_prev_first) {
						next = list_prev_entry(next, chain_node);
						limit = next;
						break;
					}

					if (list_is_last(&next->chain_node,
							 &encoder->bridge_chain)) {
						limit = next;
						break;
					}
				}

				/* Call these bridges in reverse order */
				list_for_each_entry_from_reverse(next, &encoder->bridge_chain,
								 chain_node) {
					if (next == bridge)
						break;

					drm_atomic_bridge_call_post_disable(next,
									    state);
				}
			}
		}

		drm_atomic_bridge_call_post_disable(bridge, state);

		if (limit)
			/* Jump all bridges that we have already post_disabled */
			bridge = limit;
	}
	mutex_unlock(&encoder->bridge_chain_mutex);
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);

static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge,
					      struct drm_atomic_commit *state)
{
	if (state && bridge->funcs->atomic_pre_enable)
		bridge->funcs->atomic_pre_enable(bridge, state);
}

/**
 * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in
 *					the encoder chain
 * @bridge: bridge control structure
 * @state: atomic state being committed
 *
 * Calls &drm_bridge_funcs.atomic_pre_enable op for all the bridges in the
 * encoder chain, starting from the last bridge to the first. These are called
 * before calling &drm_encoder_helper_funcs.atomic_enable
 *
 * If a bridge sets @pre_enable_prev_first, then the pre_enable for the
 * prev bridge will be called before pre_enable of this bridge.
 *
 * Example:
 * Bridge A ---> Bridge B ---> Bridge C ---> Bridge D ---> Bridge E
 *
 * With pre_enable_prev_first flag enable in Bridge B, D, E then the resulting
 * @pre_enable order would be,
 * Bridge C, Bridge D, Bridge E, Bridge A, Bridge B.
 *
 * Note: the bridge passed should be the one closest to the encoder
 */
void drm_atomic_bridge_chain_pre_enable(struct drm_bridge *bridge,
					struct drm_atomic_commit *state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *iter, *next, *limit;

	if (!bridge)
		return;

	encoder = bridge->encoder;

	mutex_lock(&encoder->bridge_chain_mutex);
	list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
		if (iter->pre_enable_prev_first) {
			next = iter;
			limit = bridge;
			list_for_each_entry_from_reverse(next,
							 &encoder->bridge_chain,
							 chain_node) {
				if (next == bridge)
					break;

				if (!next->pre_enable_prev_first) {
					/* Found first bridge that does NOT
					 * request prev to be enabled first
					 */
					limit = next;
					break;
				}
			}

			list_for_each_entry_from(next, &encoder->bridge_chain, chain_node) {
				/* Call requested prev bridge pre_enable
				 * in order.
				 */
				if (next == iter)
					/* At the first bridge to request prev
					 * bridges called first.
					 */
					break;

				drm_atomic_bridge_call_pre_enable(next, state);
			}
		}

		drm_atomic_bridge_call_pre_enable(iter, state);

		if (iter->pre_enable_prev_first)
			/* Jump all bridges that we have already pre_enabled */
			iter = limit;

		if (iter == bridge)
			break;
	}
	mutex_unlock(&encoder->bridge_chain_mutex);
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);

/**
 * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain
 * @first_bridge: bridge control structure
 * @state: atomic state being committed
 *
 * Calls &drm_bridge_funcs.atomic_enable op for all the bridges in the encoder
 * chain, starting from the first bridge to the last. These are called after
 * completing &drm_encoder_helper_funcs.atomic_enable
 *
 * Note: the bridge passed should be the one closest to the encoder
 */
void drm_atomic_bridge_chain_enable(struct drm_bridge *first_bridge,
				    struct drm_atomic_commit *state)
{
	if (!first_bridge)
		return;

	drm_for_each_bridge_in_chain_from(first_bridge, bridge)
		if (bridge->funcs->atomic_enable)
			bridge->funcs->atomic_enable(bridge, state);
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_enable);

static int drm_atomic_bridge_check(struct drm_bridge *bridge,
				   struct drm_crtc_state *crtc_state,
				   struct drm_connector_state *conn_state)
{
	if (bridge->funcs->atomic_check) {
		struct drm_bridge_state *bridge_state;
		int ret;

		bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
							       bridge);
		if (WARN_ON(!bridge_state))
			return -EINVAL;

		ret = bridge->funcs->atomic_check(bridge, bridge_state,
						  crtc_state, conn_state);
		if (ret)
			return ret;
	} else if (bridge->funcs->mode_fixup) {
		if (!bridge->funcs->mode_fixup(bridge, &crtc_state->mode,
					       &crtc_state->adjusted_mode))
			return -EINVAL;
	}

	return 0;
}

static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
				    struct drm_bridge *cur_bridge,
				    struct drm_crtc_state *crtc_state,
				    struct drm_connector_state *conn_state,
				    u32 out_bus_fmt)
{
	unsigned int i, num_in_bus_fmts = 0;
	struct drm_bridge_state *cur_state;
	struct drm_bridge *prev_bridge __free(drm_bridge_put) =
		drm_bridge_get_prev_bridge(cur_bridge);
	u32 *in_bus_fmts;
	int ret;

	cur_state = drm_atomic_get_new_bridge_state(crtc_state->state,
						    cur_bridge);

	/*
	 * If bus format negotiation is not supported by this bridge, let's
	 * pass MEDIA_BUS_FMT_FIXED to the previous bridge in the chain and
	 * hope that it can handle this situation gracefully (by providing
	 * appropriate default values).
	 */
	if (!cur_bridge->funcs->atomic_get_input_bus_fmts) {
		if (cur_bridge != first_bridge) {
			ret = select_bus_fmt_recursive(first_bridge,
						       prev_bridge, crtc_state,
						       conn_state,
						       MEDIA_BUS_FMT_FIXED);
			if (ret)
				return ret;
		}

		/*
		 * Driver does not implement the atomic state hooks, but that's
		 * fine, as long as it does not access the bridge state.
		 */
		if (cur_state) {
			cur_state->input_bus_cfg.format = MEDIA_BUS_FMT_FIXED;
			cur_state->output_bus_cfg.format = out_bus_fmt;
		}

		return 0;
	}

	/*
	 * If the driver implements ->atomic_get_input_bus_fmts() it
	 * should also implement the atomic state hooks.
	 */
	if (WARN_ON(!cur_state))
		return -EINVAL;

	in_bus_fmts = cur_bridge->funcs->atomic_get_input_bus_fmts(cur_bridge,
							cur_state,
							crtc_state,
							conn_state,
							out_bus_fmt,
							&num_in_bus_fmts);
	if (!num_in_bus_fmts)
		return -ENOTSUPP;
	else if (!in_bus_fmts)
		return -ENOMEM;

	if (first_bridge == cur_bridge) {
		cur_state->input_bus_cfg.format = in_bus_fmts[0];
		cur_state->output_bus_cfg.format = out_bus_fmt;
		kfree(in_bus_fmts);
		return 0;
	}

	for (i = 0; i < num_in_bus_fmts; i++) {
		ret = select_bus_fmt_recursive(first_bridge, prev_bridge,
					       crtc_state, conn_state,
					       in_bus_fmts[i]);
		if (ret != -ENOTSUPP)
			break;
	}

	if (!ret) {
		cur_state->input_bus_cfg.format = in_bus_fmts[i];
		cur_state->output_bus_cfg.format = out_bus_fmt;
	}

	kfree(in_bus_fmts);
	return ret;
}

static bool __pure bus_format_is_color_fmt(u32 bus_fmt, enum drm_connector_color_format fmt)
{
	if (fmt == DRM_CONNECTOR_COLOR_FORMAT_AUTO)
		return true;

	switch (bus_fmt) {
	case MEDIA_BUS_FMT_FIXED:
		return true;
	case MEDIA_BUS_FMT_RGB888_1X24:
	case MEDIA_BUS_FMT_RGB101010_1X30:
	case MEDIA_BUS_FMT_RGB121212_1X36:
	case MEDIA_BUS_FMT_RGB161616_1X48:
		return fmt == DRM_CONNECTOR_COLOR_FORMAT_RGB444;
	case MEDIA_BUS_FMT_YUV8_1X24:
	case MEDIA_BUS_FMT_YUV10_1X30:
	case MEDIA_BUS_FMT_YUV12_1X36:
	case MEDIA_BUS_FMT_YUV16_1X48:
		return fmt == DRM_CONNECTOR_COLOR_FORMAT_YCBCR444;
	case MEDIA_BUS_FMT_UYVY8_1X16:
	case MEDIA_BUS_FMT_VYUY8_1X16:
	case MEDIA_BUS_FMT_YUYV8_1X16:
	case MEDIA_BUS_FMT_YVYU8_1X16:
	case MEDIA_BUS_FMT_UYVY10_1X20:
	case MEDIA_BUS_FMT_YUYV10_1X20:
	case MEDIA_BUS_FMT_VYUY10_1X20:
	case MEDIA_BUS_FMT_YVYU10_1X20:
	case MEDIA_BUS_FMT_UYVY12_1X24:
	case MEDIA_BUS_FMT_VYUY12_1X24:
	case MEDIA_BUS_FMT_YUYV12_1X24:
	case MEDIA_BUS_FMT_YVYU12_1X24:
		return fmt == DRM_CONNECTOR_COLOR_FORMAT_YCBCR422;
	case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
	case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
	case MEDIA_BUS_FMT_UYYVYY12_0_5X36:
	case MEDIA_BUS_FMT_UYYVYY16_0_5X48:
		return fmt == DRM_CONNECTOR_COLOR_FORMAT_YCBCR420;
	default:
		return false;
	}
}

/*
 * This function is called by &drm_atomic_bridge_chain_check() just before
 * calling &drm_bridge_funcs.atomic_check() on all elements of the chain.
 * It performs bus format negotiation between bridge elements. The negotiation
 * happens in reverse order, starting from the last element in the chain up to
 * @bridge.
 *
 * Negotiation starts by retrieving supported output bus formats on the last
 * bridge element and testing them one by one. The test is recursive, meaning
 * that for each tested output format, the whole chain will be walked backward,
 * and each element will have to choose an input bus format that can be
 * transcoded to the requested output format. When a bridge element does not
 * support transcoding into a specific output format -ENOTSUPP is returned and
 * the next bridge element will have to try a different format. If none of the
 * combinations worked, -ENOTSUPP is returned and the atomic modeset will fail.
 *
 * This implementation is relying on
 * &drm_bridge_funcs.atomic_get_output_bus_fmts() and
 * &drm_bridge_funcs.atomic_get_input_bus_fmts() to gather supported
 * input/output formats.
 *
 * When &drm_bridge_funcs.atomic_get_output_bus_fmts() is not implemented by
 * the last element of the chain, &drm_atomic_bridge_chain_select_bus_fmts()
 * tries a single format: &drm_connector.display_info.bus_formats[0] if
 * available, MEDIA_BUS_FMT_FIXED otherwise.
 *
 * When &drm_bridge_funcs.atomic_get_input_bus_fmts() is not implemented,
 * &drm_atomic_bridge_chain_select_bus_fmts() skips the negotiation on the
 * bridge element that lacks this hook and asks the previous element in the
 * chain to try MEDIA_BUS_FMT_FIXED. It's up to bridge drivers to decide what
 * to do in that case (fail if they want to enforce bus format negotiation, or
 * provide a reasonable default if they need to support pipelines where not
 * all elements support bus format negotiation).
 */
static int
drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
					struct drm_crtc_state *crtc_state,
					struct drm_connector_state *conn_state)
{
	struct drm_connector *conn = conn_state->connector;
	struct drm_encoder *encoder = bridge->encoder;
	struct drm_bridge_state *last_bridge_state;
	unsigned int i, num_out_bus_fmts = 0;
	enum drm_connector_color_format fmt;
	u32 *out_bus_fmts;
	int ret = 0;

	struct drm_bridge *last_bridge __free(drm_bridge_put) =
		drm_bridge_get(list_last_entry(&encoder->bridge_chain,
					       struct drm_bridge, chain_node));
	last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
							    last_bridge);

	if (last_bridge->funcs->atomic_get_output_bus_fmts) {
		const struct drm_bridge_funcs *funcs = last_bridge->funcs;

		/*
		 * If the driver implements ->atomic_get_output_bus_fmts() it
		 * should also implement the atomic state hooks.
		 */
		if (WARN_ON(!last_bridge_state))
			return -EINVAL;

		out_bus_fmts = funcs->atomic_get_output_bus_fmts(last_bridge,
							last_bridge_state,
							crtc_state,
							conn_state,
							&num_out_bus_fmts);
		if (!num_out_bus_fmts)
			return -ENOTSUPP;
		else if (!out_bus_fmts)
			return -ENOMEM;
	} else {
		num_out_bus_fmts = 1;
		out_bus_fmts = kmalloc_obj(*out_bus_fmts);
		if (!out_bus_fmts)
			return -ENOMEM;

		if (conn->display_info.num_bus_formats &&
		    conn->display_info.bus_formats)
			out_bus_fmts[0] = conn->display_info.bus_formats[0];
		else
			out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED;
	}

	/*
	 * Instead of directly accessing conn_state.color_format, call into a
	 * connector function that allows connector implementations (e.g. for
	 * bridge connectors including HDMI bridges, where the HDMI helpers will
	 * have already chosen an appropriate output format) to override the
	 * selected format.
	 */
	fmt = drm_connector_get_color_format(conn_state);

	for (i = 0; i < num_out_bus_fmts; i++) {
		if (!bus_format_is_color_fmt(out_bus_fmts[i], fmt)) {
			drm_dbg_kms(last_bridge->dev,
				    "Skipping bus format 0x%04x as it doesn't match format %d\n",
				    out_bus_fmts[i], fmt);
			ret = -ENOTSUPP;
			continue;
		}
		ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
					       conn_state, out_bus_fmts[i]);
		if (ret != -ENOTSUPP) {
			drm_dbg_kms(last_bridge->dev,
				    "Found bridge chain ending with bus format 0x%04x\n",
				    out_bus_fmts[i]);
			break;
		}
	}

	kfree(out_bus_fmts);

	return ret;
}

static void
drm_atomic_bridge_propagate_bus_flags(struct drm_bridge *bridge,
				      struct drm_connector *conn,
				      struct drm_atomic_commit *state)
{
	struct drm_bridge_state *bridge_state, *next_bridge_state;
	u32 output_flags = 0;

	bridge_state = drm_atomic_get_new_bridge_state(state, bridge);

	/* No bridge state attached to this bridge => nothing to propagate. */
	if (!bridge_state)
		return;

	struct drm_bridge *next_bridge __free(drm_bridge_put) = drm_bridge_get_next_bridge(bridge);

	/*
	 * Let's try to apply the most common case here, that is, propagate
	 * display_info flags for the last bridge, and propagate the input
	 * flags of the next bridge element to the output end of the current
	 * bridge when the bridge is not the last one.
	 * There are exceptions to this rule, like when signal inversion is
	 * happening at the board level, but that's something drivers can deal
	 * with from their &drm_bridge_funcs.atomic_check() implementation by
	 * simply overriding the flags value we've set here.
	 */
	if (!next_bridge) {
		output_flags = conn->display_info.bus_flags;
	} else {
		next_bridge_state = drm_atomic_get_new_bridge_state(state,
								next_bridge);
		/*
		 * No bridge state attached to the next bridge, just leave the
		 * flags to 0.
		 */
		if (next_bridge_state)
			output_flags = next_bridge_state->input_bus_cfg.flags;
	}

	bridge_state->output_bus_cfg.flags = output_flags;

	/*
	 * Propagate the output flags to the input end of the bridge. Again, it's
	 * not necessarily what all bridges want, but that's what most of them
	 * do, and by doing that by default we avoid forcing drivers to
	 * duplicate the "dummy propagation" logic.
	 */
	bridge_state->input_bus_cfg.flags = output_flags;
}

/**
 * drm_atomic_bridge_chain_check() - Do an atomic check on the bridge chain
 * @bridge: bridge control structure
 * @crtc_state: new CRTC state
 * @conn_state: new connector state
 *
 * First trigger a bus format negotiation before calling
 * &drm_bridge_funcs.atomic_check() (falls back on
 * &drm_bridge_funcs.mode_fixup()) op for all the bridges in the encoder chain,
 * starting from the last bridge to the first. These are called before calling
 * &drm_encoder_helper_funcs.atomic_check()
 *
 * RETURNS:
 * 0 on success, a negative error code on failure
 */
int drm_atomic_bridge_chain_check(struct drm_bridge *bridge,
				  struct drm_crtc_state *crtc_state,
				  struct drm_connector_state *conn_state)
{
	struct drm_connector *conn = conn_state->connector;
	struct drm_encoder *encoder;
	struct drm_bridge *iter;
	int ret;

	if (!bridge)
		return 0;

	ret = drm_atomic_bridge_chain_select_bus_fmts(bridge, crtc_state,
						      conn_state);
	if (ret)
		return ret;

	encoder = bridge->encoder;
	scoped_guard(mutex, &encoder->bridge_chain_mutex) {
		list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
			int ret;

			/*
			 * Bus flags are propagated by default. If a bridge needs to
			 * tweak the input bus flags for any reason, it should happen
			 * in its &drm_bridge_funcs.atomic_check() implementation such
			 * that preceding bridges in the chain can propagate the new
			 * bus flags.
			 */
			drm_atomic_bridge_propagate_bus_flags(iter, conn,
							      crtc_state->state);

			ret = drm_atomic_bridge_check(iter, crtc_state, conn_state);
			if (ret)
				return ret;

			if (iter == bridge)
				break;
		}
	}

	return 0;
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_check);

/**
 * drm_bridge_detect - check if anything is attached to the bridge output
 * @bridge: bridge control structure
 * @connector: attached connector
 *
 * If the bridge supports output detection, as reported by the
 * DRM_BRIDGE_OP_DETECT bridge ops flag, call &drm_bridge_funcs.detect for the
 * bridge and return the connection status. Otherwise return
 * connector_status_unknown.
 *
 * RETURNS:
 * The detection status on success, or connector_status_unknown if the bridge
 * doesn't support output detection.
 */
enum drm_connector_status
drm_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector)
{
	if (!(bridge->ops & DRM_BRIDGE_OP_DETECT))
		return connector_status_unknown;

	return bridge->funcs->detect(bridge, connector);
}
EXPORT_SYMBOL_GPL(drm_bridge_detect);

/**
 * drm_bridge_get_modes - fill all modes currently valid for the sink into the
 * @connector
 * @bridge: bridge control structure
 * @connector: the connector to fill with modes
 *
 * If the bridge supports output modes retrieval, as reported by the
 * DRM_BRIDGE_OP_MODES bridge ops flag, call &drm_bridge_funcs.get_modes to
 * fill the connector with all valid modes and return the number of modes
 * added. Otherwise return 0.
 *
 * RETURNS:
 * The number of modes added to the connector.
 */
int drm_bridge_get_modes(struct drm_bridge *bridge,
			 struct drm_connector *connector)
{
	if (!(bridge->ops & DRM_BRIDGE_OP_MODES))
		return 0;

	return bridge->funcs->get_modes(bridge, connector);
}
EXPORT_SYMBOL_GPL(drm_bridge_get_modes);

/**
 * drm_bridge_edid_read - read the EDID data of the connected display
 * @bridge: bridge control structure
 * @connector: the connector to read EDID for
 *
 * If the bridge supports output EDID retrieval, as reported by the
 * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.edid_read to get
 * the EDID and return it. Otherwise return NULL.
 *
 * RETURNS:
 * The retrieved EDID on success, or NULL otherwise.
 */
const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge,
					    struct drm_connector *connector)
{
	if (!(bridge->ops & DRM_BRIDGE_OP_EDID))
		return NULL;

	return bridge->funcs->edid_read(bridge, connector);
}
EXPORT_SYMBOL_GPL(drm_bridge_edid_read);

/**
 * drm_bridge_hpd_enable - enable hot plug detection for the bridge
 * @bridge: bridge control structure
 * @cb: hot-plug detection callback
 * @data: data to be passed to the hot-plug detection callback
 *
 * Call &drm_bridge_funcs.hpd_enable if implemented and register the given @cb
 * and @data as hot plug notification callback. From now on the @cb will be
 * called with @data when an output status change is detected by the bridge,
 * until hot plug notification gets disabled with drm_bridge_hpd_disable().
 *
 * Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in
 * bridge->ops. This function shall not be called when the flag is not set.
 *
 * Only one hot plug detection callback can be registered at a time, it is an
 * error to call this function when hot plug detection is already enabled for
 * the bridge.
 */
void drm_bridge_hpd_enable(struct drm_bridge *bridge,
			   void (*cb)(void *data,
				      enum drm_connector_status status),
			   void *data)
{
	if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
		return;

	mutex_lock(&bridge->hpd_state_mutex);

	mutex_lock(&bridge->hpd_mutex);

	if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n")) {
		mutex_unlock(&bridge->hpd_mutex);
		goto unlock;
	}

	bridge->hpd_cb = cb;
	bridge->hpd_data = data;

	mutex_unlock(&bridge->hpd_mutex);

	if (bridge->funcs->hpd_enable)
		bridge->funcs->hpd_enable(bridge);

unlock:
	mutex_unlock(&bridge->hpd_state_mutex);
}
EXPORT_SYMBOL_GPL(drm_bridge_hpd_enable);

/**
 * drm_bridge_hpd_disable - disable hot plug detection for the bridge
 * @bridge: bridge control structure
 *
 * Call &drm_bridge_funcs.hpd_disable if implemented and unregister the hot
 * plug detection callback previously registered with drm_bridge_hpd_enable().
 * Once this function returns the callback will not be called by the bridge
 * when an output status change occurs.
 *
 * Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in
 * bridge->ops. This function shall not be called when the flag is not set.
 */
void drm_bridge_hpd_disable(struct drm_bridge *bridge)
{
	if (!(bridge->ops & DRM_BRIDGE_OP_HPD))
		return;

	mutex_lock(&bridge->hpd_state_mutex);
	if (bridge->funcs->hpd_disable)
		bridge->funcs->hpd_disable(bridge);

	mutex_lock(&bridge->hpd_mutex);
	bridge->hpd_cb = NULL;
	bridge->hpd_data = NULL;
	mutex_unlock(&bridge->hpd_mutex);
	mutex_unlock(&bridge->hpd_state_mutex);
}
EXPORT_SYMBOL_GPL(drm_bridge_hpd_disable);

/**
 * drm_bridge_hpd_notify - notify hot plug detection events
 * @bridge: bridge control structure
 * @status: output connection status
 *
 * Bridge drivers shall call this function to report hot plug events when they
 * detect a change in the output status, when hot plug detection has been
 * enabled by drm_bridge_hpd_enable().
 *
 * This function shall be called in a context that can sleep.
 */
void drm_bridge_hpd_notify(struct drm_bridge *bridge,
			   enum drm_connector_status status)
{
	mutex_lock(&bridge->hpd_mutex);
	if (bridge->hpd_cb)
		bridge->hpd_cb(bridge->hpd_data, status);
	mutex_unlock(&bridge->hpd_mutex);
}
EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify);

#ifdef CONFIG_OF
/**
 * of_drm_find_and_get_bridge - find the bridge corresponding to the device
 *                              node in the global bridge list
 * @np: device node
 *
 * The refcount of the returned bridge is incremented. Use drm_bridge_put()
 * when done with it.
 *
 * RETURNS:
 * drm_bridge control struct on success, NULL on failure
 */
struct drm_bridge *of_drm_find_and_get_bridge(struct device_node *np)
{
	struct drm_bridge *bridge;

	scoped_guard(mutex, &bridge_lock) {
		list_for_each_entry(bridge, &bridge_list, list)
			if (bridge->of_node == np)
				return drm_bridge_get(bridge);
	}

	return NULL;
}
EXPORT_SYMBOL(of_drm_find_and_get_bridge);

/**
 * of_drm_find_bridge - find the bridge corresponding to the device node in
 *			the global bridge list
 *
 * @np: device node
 *
 * This function is deprecated. Convert to of_drm_find_and_get_bridge()
 * instead for proper refcounting.
 *
 * The bridge returned by this function is not refcounted. This is
 * dangerous because the bridge might be deallocated even before the caller
 * has a chance to use it. To use this function you have to do one of:
 *
 * - get a reference with drm_bridge_get() as soon as possible to
 *   minimize the race window, and then drm_bridge_put() when no longer
 *   using the pointer
 *
 * - not call drm_bridge_get() or drm_bridge_put() at all, which used to
 *   be the correct practice before dynamic bridge lifetime was introduced
 *
 * - again, convert to of_drm_find_and_get_bridge(), which is the only safe
 *   thing to do
 *
 * RETURNS:
 * drm_bridge control struct on success, NULL on failure
 */
struct drm_bridge *of_drm_find_bridge(struct device_node *np)
{
	struct drm_bridge *bridge = of_drm_find_and_get_bridge(np);

	/*
	 * We need to emulate the original semantics of
	 * of_drm_find_bridge(), which was not getting any bridge
	 * reference. Being now based on of_drm_find_and_get_bridge() which
	 * gets a reference, put it before returning.
	 */
	drm_bridge_put(bridge);

	return bridge;
}
EXPORT_SYMBOL(of_drm_find_bridge);

/**
 * of_drm_get_bridge_by_endpoint - return DRM bridge connected to a port/endpoint
 * @np: device tree node containing output ports
 * @port: port in the device tree node, or -1 for the first port found
 * @endpoint: endpoint in the device tree node, or -1 for the first endpoint found
 *
 * Given a DT node's port and endpoint number, find the connected node and
 * return the associated drm_bridge device.
 *
 * The refcount of the returned bridge is incremented. Use drm_bridge_put()
 * when done with it.
 *
 * Returns a pointer to the connected drm_bridge, or a negative error on failure
 */
struct drm_bridge *of_drm_get_bridge_by_endpoint(const struct device_node *np,
						 int port, int endpoint)
{
	struct drm_bridge *bridge;

	/*
	 * of_graph_get_remote_node() produces a noisy error message if port
	 * node isn't found and the absence of the port is a legit case here,
	 * so at first we silently check whether a graph is present in the
	 * device-tree node.
	 */
	if (!of_graph_is_present(np))
		return ERR_PTR(-ENODEV);

	struct device_node *remote __free(device_node) =
		of_graph_get_remote_node(np, port, endpoint);
	if (!remote)
		return ERR_PTR(-ENODEV);

	bridge = of_drm_find_and_get_bridge(remote);
	if (!bridge)
		return ERR_PTR(-EPROBE_DEFER);

	return bridge;
}
EXPORT_SYMBOL_GPL(of_drm_get_bridge_by_endpoint);
#endif

/**
 * devm_drm_put_bridge - Release a bridge reference obtained via devm
 * @dev: device that got the bridge via devm
 * @bridge: pointer to a struct drm_bridge obtained via devm
 *
 * Same as drm_bridge_put() for bridge pointers obtained via devm functions
 * such as devm_drm_bridge_alloc().
 *
 * This function is a temporary workaround and MUST NOT be used. Manual
 * handling of bridge lifetime is inherently unsafe.
 */
void devm_drm_put_bridge(struct device *dev, struct drm_bridge *bridge)
{
	devm_release_action(dev, drm_bridge_put_void, bridge);
}
EXPORT_SYMBOL(devm_drm_put_bridge);

static void drm_bridge_debugfs_show_bridge(struct drm_printer *p,
					   struct drm_bridge *bridge,
					   unsigned int idx,
					   bool lingering,
					   bool scoped)
{
	unsigned int refcount = kref_read(&bridge->refcount);

	if (scoped)
		refcount--;

	drm_printf(p, "bridge[%u]: %ps\n", idx, bridge->funcs);

	drm_printf_indent(p, 1, "refcount: %u%s\n", refcount,
			  lingering ? " [lingering]" : "");

	drm_printf_indent(p, 1, "type: [%d] %s\n", bridge->type,
			  drm_get_connector_type_name(bridge->type));

	/* The OF node could be freed after drm_bridge_remove() */
	if (bridge->of_node && !lingering)
		drm_printf_indent(p, 1, "OF: %pOFfc\n", bridge->of_node);

	drm_printf_indent(p, 1, "ops: [0x%x]", bridge->ops);
	if (bridge->ops & DRM_BRIDGE_OP_DETECT)
		drm_puts(p, " detect");
	if (bridge->ops & DRM_BRIDGE_OP_EDID)
		drm_puts(p, " edid");
	if (bridge->ops & DRM_BRIDGE_OP_HPD)
		drm_puts(p, " hpd");
	if (bridge->ops & DRM_BRIDGE_OP_MODES)
		drm_puts(p, " modes");
	if (bridge->ops & DRM_BRIDGE_OP_HDMI)
		drm_puts(p, " hdmi");
	drm_puts(p, "\n");
}

static int allbridges_show(struct seq_file *m, void *data)
{
	struct drm_printer p = drm_seq_file_printer(m);
	struct drm_bridge *bridge;
	unsigned int idx = 0;

	mutex_lock(&bridge_lock);

	list_for_each_entry(bridge, &bridge_list, list)
		drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, false);

	list_for_each_entry(bridge, &bridge_lingering_list, list)
		drm_bridge_debugfs_show_bridge(&p, bridge, idx++, true, false);

	mutex_unlock(&bridge_lock);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(allbridges);

static int encoder_bridges_show(struct seq_file *m, void *data)
{
	struct drm_encoder *encoder = m->private;
	struct drm_printer p = drm_seq_file_printer(m);
	unsigned int idx = 0;

	drm_for_each_bridge_in_chain(encoder, bridge)
		drm_bridge_debugfs_show_bridge(&p, bridge, idx++, false, true);

	return 0;
}
DEFINE_SHOW_ATTRIBUTE(encoder_bridges);

void drm_bridge_debugfs_params(struct dentry *root)
{
	debugfs_create_file("bridges", 0444, root, NULL, &allbridges_fops);
}

void drm_bridge_debugfs_encoder_params(struct dentry *root,
				       struct drm_encoder *encoder)
{
	/* bridges list */
	debugfs_create_file("bridges", 0444, root, encoder, &encoder_bridges_fops);
}

MODULE_AUTHOR("Ajay Kumar <ajaykumar.rs@samsung.com>");
MODULE_DESCRIPTION("DRM bridge infrastructure");
MODULE_LICENSE("GPL and additional rights");
