// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>

#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_connector.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_probe_helper.h>

/**
 * DOC: overview
 *
 * The DRM bridge connector helper object provides a DRM connector
 * implementation that wraps a chain of &struct drm_bridge. The connector
 * operations are fully implemented based on the operations of the bridges in
 * the chain, and don't require any intervention from the display controller
 * driver at runtime.
 *
 * To use the helper, display controller drivers create a bridge connector with
 * a call to drm_bridge_connector_init(). This associates the newly created
 * connector with the chain of bridges passed to the function and registers it
 * with the DRM device. At that point the connector becomes fully usable, no
 * further operation is needed.
 *
 * The DRM bridge connector operations are implemented based on the operations
 * provided by the bridges in the chain. Each connector operation is delegated
 * to the bridge closest to the connector (at the end of the chain) that
 * provides the relevant functionality.
 *
 * To make use of this helper, all bridges in the chain shall report bridge
 * operation flags (&drm_bridge->ops) and bridge output type
 * (&drm_bridge->type), as well as the DRM_BRIDGE_ATTACH_NO_CONNECTOR attach
 * flag (none of the bridges shall create a DRM connector directly).
 */

/**
 * struct drm_bridge_connector - A connector backed by a chain of bridges
 */
struct drm_bridge_connector {
	/**
	 * @base: The base DRM connector
	 */
	struct drm_connector base;
	/**
	 * @encoder:
	 *
	 * The encoder at the start of the bridges chain.
	 */
	struct drm_encoder *encoder;
	/**
	 * @bridge_edid:
	 *
	 * The last bridge in the chain (closest to the connector) that provides
	 * EDID read support, if any (see &DRM_BRIDGE_OP_EDID).
	 */
	struct drm_bridge *bridge_edid;
	/**
	 * @bridge_hpd:
	 *
	 * The last bridge in the chain (closest to the connector) that provides
	 * hot-plug detection notification, if any (see &DRM_BRIDGE_OP_HPD).
	 */
	struct drm_bridge *bridge_hpd;
	/**
	 * @bridge_detect:
	 *
	 * The last bridge in the chain (closest to the connector) that provides
	 * connector detection, if any (see &DRM_BRIDGE_OP_DETECT).
	 */
	struct drm_bridge *bridge_detect;
	/**
	 * @bridge_modes:
	 *
	 * The last bridge in the chain (closest to the connector) that provides
	 * connector modes detection, if any (see &DRM_BRIDGE_OP_MODES).
	 */
	struct drm_bridge *bridge_modes;
};

#define to_drm_bridge_connector(x) \
	container_of(x, struct drm_bridge_connector, base)

/* -----------------------------------------------------------------------------
 * Bridge Connector Hot-Plug Handling
 */

static void drm_bridge_connector_hpd_notify(struct drm_connector *connector,
					    enum drm_connector_status status)
{
	struct drm_bridge_connector *bridge_connector =
		to_drm_bridge_connector(connector);
	struct drm_bridge *bridge;

	/* Notify all bridges in the pipeline of hotplug events. */
	drm_for_each_bridge_in_chain(bridge_connector->encoder, bridge) {
		if (bridge->funcs->hpd_notify)
			bridge->funcs->hpd_notify(bridge, status);
	}
}

static void drm_bridge_connector_hpd_cb(void *cb_data,
					enum drm_connector_status status)
{
	struct drm_bridge_connector *drm_bridge_connector = cb_data;
	struct drm_connector *connector = &drm_bridge_connector->base;
	struct drm_device *dev = connector->dev;
	enum drm_connector_status old_status;

	mutex_lock(&dev->mode_config.mutex);
	old_status = connector->status;
	connector->status = status;
	mutex_unlock(&dev->mode_config.mutex);

	if (old_status == status)
		return;

	drm_bridge_connector_hpd_notify(connector, status);

	drm_kms_helper_hotplug_event(dev);
}

/**
 * drm_bridge_connector_enable_hpd - Enable hot-plug detection for the connector
 * @connector: The DRM bridge connector
 *
 * This function enables hot-plug detection for the given bridge connector.
 * This is typically used by display drivers in their resume handler.
 */
void drm_bridge_connector_enable_hpd(struct drm_connector *connector)
{
	struct drm_bridge_connector *bridge_connector =
		to_drm_bridge_connector(connector);
	struct drm_bridge *hpd = bridge_connector->bridge_hpd;

	if (hpd)
		drm_bridge_hpd_enable(hpd, drm_bridge_connector_hpd_cb,
				      bridge_connector);
}
EXPORT_SYMBOL_GPL(drm_bridge_connector_enable_hpd);

/**
 * drm_bridge_connector_disable_hpd - Disable hot-plug detection for the
 * connector
 * @connector: The DRM bridge connector
 *
 * This function disables hot-plug detection for the given bridge connector.
 * This is typically used by display drivers in their suspend handler.
 */
void drm_bridge_connector_disable_hpd(struct drm_connector *connector)
{
	struct drm_bridge_connector *bridge_connector =
		to_drm_bridge_connector(connector);
	struct drm_bridge *hpd = bridge_connector->bridge_hpd;

	if (hpd)
		drm_bridge_hpd_disable(hpd);
}
EXPORT_SYMBOL_GPL(drm_bridge_connector_disable_hpd);

/* -----------------------------------------------------------------------------
 * Bridge Connector Functions
 */

static enum drm_connector_status
drm_bridge_connector_detect(struct drm_connector *connector, bool force)
{
	struct drm_bridge_connector *bridge_connector =
		to_drm_bridge_connector(connector);
	struct drm_bridge *detect = bridge_connector->bridge_detect;
	enum drm_connector_status status;

	if (detect) {
		status = detect->funcs->detect(detect);

		drm_bridge_connector_hpd_notify(connector, status);
	} else {
		switch (connector->connector_type) {
		case DRM_MODE_CONNECTOR_DPI:
		case DRM_MODE_CONNECTOR_LVDS:
		case DRM_MODE_CONNECTOR_DSI:
			status = connector_status_connected;
			break;
		default:
			status = connector_status_unknown;
			break;
		}
	}

	return status;
}

static void drm_bridge_connector_destroy(struct drm_connector *connector)
{
	struct drm_bridge_connector *bridge_connector =
		to_drm_bridge_connector(connector);

	if (bridge_connector->bridge_hpd) {
		struct drm_bridge *hpd = bridge_connector->bridge_hpd;

		drm_bridge_hpd_disable(hpd);
	}

	drm_connector_unregister(connector);
	drm_connector_cleanup(connector);

	kfree(bridge_connector);
}

static const struct drm_connector_funcs drm_bridge_connector_funcs = {
	.reset = drm_atomic_helper_connector_reset,
	.detect = drm_bridge_connector_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_bridge_connector_destroy,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

/* -----------------------------------------------------------------------------
 * Bridge Connector Helper Functions
 */

static int drm_bridge_connector_get_modes_edid(struct drm_connector *connector,
					       struct drm_bridge *bridge)
{
	enum drm_connector_status status;
	struct edid *edid;
	int n;

	status = drm_bridge_connector_detect(connector, false);
	if (status != connector_status_connected)
		goto no_edid;

	edid = bridge->funcs->get_edid(bridge, connector);
	if (!edid || !drm_edid_is_valid(edid)) {
		kfree(edid);
		goto no_edid;
	}

	drm_connector_update_edid_property(connector, edid);
	n = drm_add_edid_modes(connector, edid);

	kfree(edid);
	return n;

no_edid:
	drm_connector_update_edid_property(connector, NULL);
	return 0;
}

static int drm_bridge_connector_get_modes(struct drm_connector *connector)
{
	struct drm_bridge_connector *bridge_connector =
		to_drm_bridge_connector(connector);
	struct drm_bridge *bridge;

	/*
	 * If display exposes EDID, then we parse that in the normal way to
	 * build table of supported modes.
	 */
	bridge = bridge_connector->bridge_edid;
	if (bridge)
		return drm_bridge_connector_get_modes_edid(connector, bridge);

	/*
	 * Otherwise if the display pipeline reports modes (e.g. with a fixed
	 * resolution panel or an analog TV output), query it.
	 */
	bridge = bridge_connector->bridge_modes;
	if (bridge)
		return bridge->funcs->get_modes(bridge, connector);

	/*
	 * We can't retrieve modes, which can happen for instance for a DVI or
	 * VGA output with the DDC bus unconnected. The KMS core will add the
	 * default modes.
	 */
	return 0;
}

static const struct drm_connector_helper_funcs drm_bridge_connector_helper_funcs = {
	.get_modes = drm_bridge_connector_get_modes,
	/* No need for .mode_valid(), the bridges are checked by the core. */
};

/* -----------------------------------------------------------------------------
 * Bridge Connector Initialisation
 */

/**
 * drm_bridge_connector_init - Initialise a connector for a chain of bridges
 * @drm: the DRM device
 * @encoder: the encoder where the bridge chain starts
 *
 * Allocate, initialise and register a &drm_bridge_connector with the @drm
 * device. The connector is associated with a chain of bridges that starts at
 * the @encoder. All bridges in the chain shall report bridge operation flags
 * (&drm_bridge->ops) and bridge output type (&drm_bridge->type), and none of
 * them may create a DRM connector directly.
 *
 * Returns a pointer to the new connector on success, or a negative error
 * pointer otherwise.
 */
struct drm_connector *drm_bridge_connector_init(struct drm_device *drm,
						struct drm_encoder *encoder)
{
	struct drm_bridge_connector *bridge_connector;
	struct drm_connector *connector;
	struct i2c_adapter *ddc = NULL;
	struct drm_bridge *bridge;
	int connector_type;

	bridge_connector = kzalloc(sizeof(*bridge_connector), GFP_KERNEL);
	if (!bridge_connector)
		return ERR_PTR(-ENOMEM);

	bridge_connector->encoder = encoder;

	/*
	 * TODO: Handle doublescan_allowed, stereo_allowed and
	 * ycbcr_420_allowed.
	 */
	connector = &bridge_connector->base;
	connector->interlace_allowed = true;

	/*
	 * Initialise connector status handling. First locate the furthest
	 * bridges in the pipeline that support HPD and output detection. Then
	 * initialise the connector polling mode, using HPD if available and
	 * falling back to polling if supported. If neither HPD nor output
	 * detection are available, we don't support hotplug detection at all.
	 */
	connector_type = DRM_MODE_CONNECTOR_Unknown;
	drm_for_each_bridge_in_chain(encoder, bridge) {
		if (!bridge->interlace_allowed)
			connector->interlace_allowed = false;

		if (bridge->ops & DRM_BRIDGE_OP_EDID)
			bridge_connector->bridge_edid = bridge;
		if (bridge->ops & DRM_BRIDGE_OP_HPD)
			bridge_connector->bridge_hpd = bridge;
		if (bridge->ops & DRM_BRIDGE_OP_DETECT)
			bridge_connector->bridge_detect = bridge;
		if (bridge->ops & DRM_BRIDGE_OP_MODES)
			bridge_connector->bridge_modes = bridge;

		if (!drm_bridge_get_next_bridge(bridge))
			connector_type = bridge->type;

		if (bridge->ddc)
			ddc = bridge->ddc;
	}

	if (connector_type == DRM_MODE_CONNECTOR_Unknown) {
		kfree(bridge_connector);
		return ERR_PTR(-EINVAL);
	}

	drm_connector_init_with_ddc(drm, connector, &drm_bridge_connector_funcs,
				    connector_type, ddc);
	drm_connector_helper_add(connector, &drm_bridge_connector_helper_funcs);

	if (bridge_connector->bridge_hpd)
		connector->polled = DRM_CONNECTOR_POLL_HPD;
	else if (bridge_connector->bridge_detect)
		connector->polled = DRM_CONNECTOR_POLL_CONNECT
				  | DRM_CONNECTOR_POLL_DISCONNECT;

	return connector;
}
EXPORT_SYMBOL_GPL(drm_bridge_connector_init);
