// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
 * Author: Rob Clark <rob@ti.com>
 */

#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_probe_helper.h>

#include "omap_drv.h"

/*
 * connector funcs
 */

#define to_omap_connector(x) container_of(x, struct omap_connector, base)

struct omap_connector {
	struct drm_connector base;
	struct omap_dss_device *output;
};

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

static void omap_connector_destroy(struct drm_connector *connector)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);

	DBG("%s", connector->name);

	drm_connector_unregister(connector);
	drm_connector_cleanup(connector);

	omapdss_device_put(omap_connector->output);

	kfree(omap_connector);
}

static int omap_connector_get_modes(struct drm_connector *connector)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);
	struct omap_dss_device *dssdev = NULL;
	struct omap_dss_device *d;

	DBG("%s", connector->name);

	/*
	 * If the display pipeline reports modes (e.g. with a fixed resolution
	 * panel or an analog TV output), query it.
	 */
	for (d = omap_connector->output; d; d = d->next) {
		if (d->ops_flags & OMAP_DSS_DEVICE_OP_MODES)
			dssdev = d;
	}

	if (dssdev)
		return dssdev->ops->get_modes(dssdev, connector);

	/* We can't retrieve modes. The KMS core will add the default modes. */
	return 0;
}

enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev,
					const struct drm_display_mode *mode,
					struct drm_display_mode *adjusted_mode)
{
	int ret;

	drm_mode_copy(adjusted_mode, mode);

	for (; dssdev; dssdev = dssdev->next) {
		if (!dssdev->ops || !dssdev->ops->check_timings)
			continue;

		ret = dssdev->ops->check_timings(dssdev, adjusted_mode);
		if (ret)
			return MODE_BAD;
	}

	return MODE_OK;
}

static enum drm_mode_status omap_connector_mode_valid(struct drm_connector *connector,
				 struct drm_display_mode *mode)
{
	struct omap_connector *omap_connector = to_omap_connector(connector);
	struct drm_display_mode new_mode = {};
	enum drm_mode_status status;

	status = omap_connector_mode_fixup(omap_connector->output, mode,
					   &new_mode);
	if (status != MODE_OK)
		goto done;

	/* Check if vrefresh is still valid. */
	if (drm_mode_vrefresh(mode) != drm_mode_vrefresh(&new_mode))
		status = MODE_NOCLOCK;

done:
	DBG("connector: mode %s: " DRM_MODE_FMT,
			(status == MODE_OK) ? "valid" : "invalid",
			DRM_MODE_ARG(mode));

	return status;
}

static const struct drm_connector_funcs omap_connector_funcs = {
	.reset = drm_atomic_helper_connector_reset,
	.detect = omap_connector_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = omap_connector_destroy,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static const struct drm_connector_helper_funcs omap_connector_helper_funcs = {
	.get_modes = omap_connector_get_modes,
	.mode_valid = omap_connector_mode_valid,
};

/* initialize connector */
struct drm_connector *omap_connector_init(struct drm_device *dev,
					  struct omap_dss_device *output,
					  struct drm_encoder *encoder)
{
	struct drm_connector *connector = NULL;
	struct omap_connector *omap_connector;

	DBG("%s", output->name);

	omap_connector = kzalloc(sizeof(*omap_connector), GFP_KERNEL);
	if (!omap_connector)
		goto fail;

	omap_connector->output = omapdss_device_get(output);

	connector = &omap_connector->base;
	connector->interlace_allowed = 1;
	connector->doublescan_allowed = 0;

	drm_connector_init(dev, connector, &omap_connector_funcs,
			   DRM_MODE_CONNECTOR_DSI);
	drm_connector_helper_add(connector, &omap_connector_helper_funcs);

	return connector;

fail:
	if (connector)
		omap_connector_destroy(connector);

	return NULL;
}
