/*
 * Copyright (C) 2016 ARM Limited
 * Author: Liviu Dudau <Liviu.Dudau@arm.com>
 *
 * Dummy encoder and connector that use the OF to "discover" the attached
 * display timings. Can be used in situations where the encoder and connector's
 * functionality are emulated and no setup steps are needed, or to describe
 * attached panels for which no driver exists but can be used without
 * additional hardware setup.
 *
 * The encoder also uses the component framework so that it can be a quick
 * replacement for existing drivers when testing in an emulated environment.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 *
 */

#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_of.h>
#include <linux/component.h>
#include <video/display_timing.h>
#include <video/of_display_timing.h>
#include <video/videomode.h>

struct drm_virt_priv {
	struct drm_connector connector;
	struct drm_encoder encoder;
	struct display_timings *timings;
};

#define connector_to_drm_virt_priv(x) \
	container_of(x, struct drm_virt_priv, connector)

#define encoder_to_drm_virt_priv(x) \
	container_of(x, struct drm_virt_priv, encoder)

static void drm_virtcon_destroy(struct drm_connector *connector)
{
	struct drm_virt_priv *conn = connector_to_drm_virt_priv(connector);

	drm_connector_cleanup(connector);
	display_timings_release(conn->timings);
}

static enum drm_connector_status
drm_virtcon_detect(struct drm_connector *connector, bool force)
{
	return connector_status_connected;
}

static const struct drm_connector_funcs drm_virtcon_funcs = {
	.reset = drm_atomic_helper_connector_reset,
	.detect	= drm_virtcon_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_virtcon_destroy,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static int drm_virtcon_get_modes(struct drm_connector *connector)
{
	struct drm_virt_priv *conn = connector_to_drm_virt_priv(connector);
	struct display_timings *timings = conn->timings;
	int i;

	for (i = 0; i < timings->num_timings; i++) {
		struct drm_display_mode *mode = drm_mode_create(connector->dev);
		struct videomode vm;

		if (videomode_from_timings(timings, &vm, i))
			break;

		drm_display_mode_from_videomode(&vm, mode);
		mode->type = DRM_MODE_TYPE_DRIVER;
		if (timings->native_mode == i)
			mode->type = DRM_MODE_TYPE_PREFERRED;

		drm_mode_set_name(mode);
		drm_mode_probed_add(connector, mode);
	}

	return i;
}

static int drm_virtcon_mode_valid(struct drm_connector *connector,
				   struct drm_display_mode *mode)
{
	return MODE_OK;
}

struct drm_encoder *drm_virtcon_best_encoder(struct drm_connector *connector)
{
	struct drm_virt_priv *priv = connector_to_drm_virt_priv(connector);

	return &priv->encoder;
}

struct drm_encoder *
drm_virtcon_atomic_best_encoder(struct drm_connector *connector,
				 struct drm_connector_state *connector_state)
{
	struct drm_virt_priv *priv = connector_to_drm_virt_priv(connector);

	return &priv->encoder;
}

static const struct drm_connector_helper_funcs drm_virtcon_helper_funcs = {
	.get_modes = drm_virtcon_get_modes,
	.mode_valid = drm_virtcon_mode_valid,
	.best_encoder = drm_virtcon_best_encoder,
	.atomic_best_encoder = drm_virtcon_atomic_best_encoder,
};

static void drm_vencoder_destroy(struct drm_encoder *encoder)
{
	drm_encoder_cleanup(encoder);
}

static const struct drm_encoder_funcs drm_vencoder_funcs = {
	.destroy = drm_vencoder_destroy,
};

static void drm_vencoder_dpms(struct drm_encoder *encoder, int mode)
{
	/* nothing needed */
}

static bool drm_vencoder_mode_fixup(struct drm_encoder *encoder,
				    const struct drm_display_mode *mode,
				    struct drm_display_mode *adjusted_mode)
{
	/* nothing needed */
	return true;
}

static void drm_vencoder_prepare(struct drm_encoder *encoder)
{
	drm_vencoder_dpms(encoder, DRM_MODE_DPMS_OFF);
}

static void drm_vencoder_commit(struct drm_encoder *encoder)
{
	drm_vencoder_dpms(encoder, DRM_MODE_DPMS_ON);
}

static void drm_vencoder_mode_set(struct drm_encoder *encoder,
				  struct drm_display_mode *mode,
				  struct drm_display_mode *adjusted_mode)
{
	/* nothing needed */
}

static const struct drm_encoder_helper_funcs drm_vencoder_helper_funcs = {
	.dpms		= drm_vencoder_dpms,
	.mode_fixup	= drm_vencoder_mode_fixup,
	.prepare	= drm_vencoder_prepare,
	.commit		= drm_vencoder_commit,
	.mode_set	= drm_vencoder_mode_set,
};

static int drm_vencoder_bind(struct device *dev, struct device *master,
			     void *data)
{
	struct drm_encoder *encoder;
	struct drm_virt_priv *con;
	struct drm_connector *connector;
	struct drm_device *drm = data;
	u32 crtcs = 0;
	int ret;

	con = devm_kzalloc(dev, sizeof(*con), GFP_KERNEL);
	if (!con)
		return -ENOMEM;

	dev_set_drvdata(dev, con);
	connector = &con->connector;
	encoder = &con->encoder;

	if (dev->of_node) {
		struct drm_bridge *bridge;
		crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
		bridge = of_drm_find_bridge(dev->of_node);
		if (bridge) {
			ret = drm_bridge_attach(encoder, bridge, NULL);
			if (ret) {
				DRM_ERROR("Failed to initialize bridge\n");
				return ret;
			}
		}
		con->timings = of_get_display_timings(dev->of_node);
		if (!con->timings) {
			dev_err(dev, "failed to get display panel timings\n");
			return ENXIO;
		}
	}

	/* If no CRTCs were found, fall back to the old encoder's behaviour */
	if (crtcs == 0) {
		dev_warn(dev, "Falling back to first CRTC\n");
		crtcs = 1 << 0;
	}

	encoder->possible_crtcs = crtcs ? crtcs : 1;
	encoder->possible_clones = 0;

	ret = drm_encoder_init(drm, encoder, &drm_vencoder_funcs,
			       DRM_MODE_ENCODER_VIRTUAL, NULL);
	if (ret)
		goto encoder_init_err;

	drm_encoder_helper_add(encoder, &drm_vencoder_helper_funcs);

	/* bogus values, pretend we're a 24" screen for DPI calculations */
	connector->display_info.width_mm = 519;
	connector->display_info.height_mm = 324;
	connector->interlace_allowed = false;
	connector->doublescan_allowed = false;
	connector->polled = 0;

	ret = drm_connector_init(drm, connector, &drm_virtcon_funcs,
				 DRM_MODE_CONNECTOR_VIRTUAL);
	if (ret)
		goto connector_init_err;

	drm_connector_helper_add(connector, &drm_virtcon_helper_funcs);

	drm_connector_register(connector);

	ret = drm_mode_connector_attach_encoder(connector, encoder);
	if (ret)
		goto attach_err;

	return ret;

attach_err:
	drm_connector_unregister(connector);
	drm_connector_cleanup(connector);
connector_init_err:
	drm_encoder_cleanup(encoder);
encoder_init_err:
	display_timings_release(con->timings);

	return ret;
};

static void drm_vencoder_unbind(struct device *dev, struct device *master,
				void *data)
{
	struct drm_virt_priv *con = dev_get_drvdata(dev);

	drm_connector_unregister(&con->connector);
	drm_connector_cleanup(&con->connector);
	drm_encoder_cleanup(&con->encoder);
	display_timings_release(con->timings);
}

static const struct component_ops drm_vencoder_ops = {
	.bind = drm_vencoder_bind,
	.unbind = drm_vencoder_unbind,
};

static int drm_vencoder_probe(struct platform_device *pdev)
{
	return component_add(&pdev->dev, &drm_vencoder_ops);
}

static int drm_vencoder_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &drm_vencoder_ops);
	return 0;
}

static const struct of_device_id drm_vencoder_of_match[] = {
	{ .compatible = "drm,virtual-encoder", },
	{},
};
MODULE_DEVICE_TABLE(of, drm_vencoder_of_match);

static struct platform_driver drm_vencoder_driver = {
	.probe = drm_vencoder_probe,
	.remove = drm_vencoder_remove,
	.driver = {
		.name = "drm_vencoder",
		.of_match_table = drm_vencoder_of_match,
	},
};

module_platform_driver(drm_vencoder_driver);

MODULE_AUTHOR("Liviu Dudau");
MODULE_DESCRIPTION("Virtual DRM Encoder");
MODULE_LICENSE("GPL v2");
