/*
 * 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/err.h>
#include <linux/media-bus-format.h>
#include <linux/module.h>
#include <linux/mutex.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.
 */

static DEFINE_MUTEX(bridge_lock);
static LIST_HEAD(bridge_list);

/**
 * drm_bridge_add - add the given bridge to the global bridge list
 *
 * @bridge: bridge control structure
 */
void drm_bridge_add(struct drm_bridge *bridge)
{
	mutex_init(&bridge->hpd_mutex);

	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 - remove the given bridge from the global bridge list
 *
 * @bridge: bridge control structure
 */
void drm_bridge_remove(struct drm_bridge *bridge)
{
	mutex_lock(&bridge_lock);
	list_del_init(&bridge->list);
	mutex_unlock(&bridge_lock);

	mutex_destroy(&bridge->hpd_mutex);
}
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 const struct drm_private_state_funcs drm_bridge_priv_state_funcs = {
	.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.
 *
 * 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 (previous && (!previous->dev || previous->encoder != encoder))
		return -EINVAL;

	if (bridge->dev)
		return -EBUSY;

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

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

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

	if (bridge->funcs->atomic_reset) {
		struct drm_bridge_state *state;

		state = bridge->funcs->atomic_reset(bridge);
		if (IS_ERR(state)) {
			ret = PTR_ERR(state);
			goto err_detach_bridge;
		}

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

	return 0;

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

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

	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);

	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;

	if (bridge->funcs->atomic_reset)
		drm_atomic_private_obj_fini(&bridge->base);

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

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

/**
 * 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.pre_enable, &drm_bridge_funcs.enable,
 *   &drm_bridge_funcs.disable and &drm_bridge_funcs.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.
 * @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 *bridge,
			    const struct drm_display_info *info,
			    const struct drm_display_mode *mode)
{
	struct drm_encoder *encoder;

	if (!bridge)
		return MODE_OK;

	encoder = bridge->encoder;
	list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
		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
 * @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 *bridge,
			       const struct drm_display_mode *mode,
			       const struct drm_display_mode *adjusted_mode)
{
	struct drm_encoder *encoder;

	if (!bridge)
		return;

	encoder = bridge->encoder;
	list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
		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
 * @old_state: old atomic state
 *
 * Calls &drm_bridge_funcs.atomic_disable (falls back on
 * &drm_bridge_funcs.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_state *old_state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *iter;

	if (!bridge)
		return;

	encoder = bridge->encoder;
	list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) {
		if (iter->funcs->atomic_disable) {
			struct drm_bridge_state *old_bridge_state;

			old_bridge_state =
				drm_atomic_get_old_bridge_state(old_state,
								iter);
			if (WARN_ON(!old_bridge_state))
				return;

			iter->funcs->atomic_disable(iter, old_bridge_state);
		} else if (iter->funcs->disable) {
			iter->funcs->disable(iter);
		}

		if (iter == bridge)
			break;
	}
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_disable);

static void drm_atomic_bridge_call_post_disable(struct drm_bridge *bridge,
						struct drm_atomic_state *old_state)
{
	if (old_state && bridge->funcs->atomic_post_disable) {
		struct drm_bridge_state *old_bridge_state;

		old_bridge_state =
			drm_atomic_get_old_bridge_state(old_state,
							bridge);
		if (WARN_ON(!old_bridge_state))
			return;

		bridge->funcs->atomic_post_disable(bridge,
						   old_bridge_state);
	} else if (bridge->funcs->post_disable) {
		bridge->funcs->post_disable(bridge);
	}
}

/**
 * drm_atomic_bridge_chain_post_disable - cleans up after disabling all bridges
 *					  in the encoder chain
 * @bridge: bridge control structure
 * @old_state: old atomic state
 *
 * Calls &drm_bridge_funcs.atomic_post_disable (falls back on
 * &drm_bridge_funcs.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_state *old_state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *next, *limit;

	if (!bridge)
		return;

	encoder = bridge->encoder;

	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,
									    old_state);
				}
			}
		}

		drm_atomic_bridge_call_post_disable(bridge, old_state);

		if (limit)
			/* Jump all bridges that we have already post_disabled */
			bridge = limit;
	}
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_post_disable);

static void drm_atomic_bridge_call_pre_enable(struct drm_bridge *bridge,
					      struct drm_atomic_state *old_state)
{
	if (old_state && bridge->funcs->atomic_pre_enable) {
		struct drm_bridge_state *old_bridge_state;

		old_bridge_state =
			drm_atomic_get_old_bridge_state(old_state,
							bridge);
		if (WARN_ON(!old_bridge_state))
			return;

		bridge->funcs->atomic_pre_enable(bridge, old_bridge_state);
	} else if (bridge->funcs->pre_enable) {
		bridge->funcs->pre_enable(bridge);
	}
}

/**
 * drm_atomic_bridge_chain_pre_enable - prepares for enabling all bridges in
 *					the encoder chain
 * @bridge: bridge control structure
 * @old_state: old atomic state
 *
 * Calls &drm_bridge_funcs.atomic_pre_enable (falls back on
 * &drm_bridge_funcs.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_state *old_state)
{
	struct drm_encoder *encoder;
	struct drm_bridge *iter, *next, *limit;

	if (!bridge)
		return;

	encoder = bridge->encoder;

	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, old_state);
			}
		}

		drm_atomic_bridge_call_pre_enable(iter, old_state);

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

		if (iter == bridge)
			break;
	}
}
EXPORT_SYMBOL(drm_atomic_bridge_chain_pre_enable);

/**
 * drm_atomic_bridge_chain_enable - enables all bridges in the encoder chain
 * @bridge: bridge control structure
 * @old_state: old atomic state
 *
 * Calls &drm_bridge_funcs.atomic_enable (falls back on
 * &drm_bridge_funcs.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 *bridge,
				    struct drm_atomic_state *old_state)
{
	struct drm_encoder *encoder;

	if (!bridge)
		return;

	encoder = bridge->encoder;
	list_for_each_entry_from(bridge, &encoder->bridge_chain, chain_node) {
		if (bridge->funcs->atomic_enable) {
			struct drm_bridge_state *old_bridge_state;

			old_bridge_state =
				drm_atomic_get_old_bridge_state(old_state,
								bridge);
			if (WARN_ON(!old_bridge_state))
				return;

			bridge->funcs->atomic_enable(bridge, old_bridge_state);
		} else if (bridge->funcs->enable) {
			bridge->funcs->enable(bridge);
		}
	}
}
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;
	u32 *in_bus_fmts;
	int ret;

	prev_bridge = drm_bridge_get_prev_bridge(cur_bridge);
	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;
}

/*
 * 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;
	struct drm_bridge *last_bridge;
	u32 *out_bus_fmts;
	int ret = 0;

	last_bridge = 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(sizeof(*out_bus_fmts), GFP_KERNEL);
		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;
	}

	for (i = 0; i < num_out_bus_fmts; i++) {
		ret = select_bus_fmt_recursive(bridge, last_bridge, crtc_state,
					       conn_state, out_bus_fmts[i]);
		if (ret != -ENOTSUPP)
			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_state *state)
{
	struct drm_bridge_state *bridge_state, *next_bridge_state;
	struct drm_bridge *next_bridge;
	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;

	next_bridge = 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;
	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
 *
 * 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)
{
	if (!(bridge->ops & DRM_BRIDGE_OP_DETECT))
		return connector_status_unknown;

	return bridge->funcs->detect(bridge);
}
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_mutex);

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

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

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

unlock:
	mutex_unlock(&bridge->hpd_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_mutex);
	if (bridge->funcs->hpd_disable)
		bridge->funcs->hpd_disable(bridge);

	bridge->hpd_cb = NULL;
	bridge->hpd_data = NULL;
	mutex_unlock(&bridge->hpd_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_bridge - find the bridge corresponding to the device node in
 *			the global bridge list
 *
 * @np: device node
 *
 * 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;

	mutex_lock(&bridge_lock);

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

	mutex_unlock(&bridge_lock);
	return NULL;
}
EXPORT_SYMBOL(of_drm_find_bridge);
#endif

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