/*
 * drivers/staging/omapdrm/omap_encoder.c
 *
 * Copyright (C) 2011 Texas Instruments
 * Author: Rob Clark <rob@ti.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "omap_drv.h"

#include "drm_crtc.h"
#include "drm_crtc_helper.h"

/*
 * encoder funcs
 */

#define to_omap_encoder(x) container_of(x, struct omap_encoder, base)

struct omap_encoder {
	struct drm_encoder base;
	struct omap_overlay_manager *mgr;
};

static void omap_encoder_destroy(struct drm_encoder *encoder)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	DBG("%s", omap_encoder->mgr->name);
	drm_encoder_cleanup(encoder);
	kfree(omap_encoder);
}

static void omap_encoder_dpms(struct drm_encoder *encoder, int mode)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	DBG("%s: %d", omap_encoder->mgr->name, mode);
}

static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
				  struct drm_display_mode *mode,
				  struct drm_display_mode *adjusted_mode)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	DBG("%s", omap_encoder->mgr->name);
	return true;
}

static void omap_encoder_mode_set(struct drm_encoder *encoder,
				struct drm_display_mode *mode,
				struct drm_display_mode *adjusted_mode)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	struct drm_device *dev = encoder->dev;
	struct omap_drm_private *priv = dev->dev_private;
	int i;

	mode = adjusted_mode;

	DBG("%s: set mode: %dx%d", omap_encoder->mgr->name,
			mode->hdisplay, mode->vdisplay);

	for (i = 0; i < priv->num_connectors; i++) {
		struct drm_connector *connector = priv->connectors[i];
		if (connector->encoder == encoder) {
			omap_connector_mode_set(connector, mode);
		}
	}
}

static void omap_encoder_prepare(struct drm_encoder *encoder)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	struct drm_encoder_helper_funcs *encoder_funcs =
				encoder->helper_private;
	DBG("%s", omap_encoder->mgr->name);
	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
}

static void omap_encoder_commit(struct drm_encoder *encoder)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	struct drm_encoder_helper_funcs *encoder_funcs =
				encoder->helper_private;
	DBG("%s", omap_encoder->mgr->name);
	omap_encoder->mgr->apply(omap_encoder->mgr);
	encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
}

static const struct drm_encoder_funcs omap_encoder_funcs = {
	.destroy = omap_encoder_destroy,
};

static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
	.dpms = omap_encoder_dpms,
	.mode_fixup = omap_encoder_mode_fixup,
	.mode_set = omap_encoder_mode_set,
	.prepare = omap_encoder_prepare,
	.commit = omap_encoder_commit,
};

struct omap_overlay_manager *omap_encoder_get_manager(
		struct drm_encoder *encoder)
{
	struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
	return omap_encoder->mgr;
}

/* initialize encoder */
struct drm_encoder *omap_encoder_init(struct drm_device *dev,
		struct omap_overlay_manager *mgr)
{
	struct drm_encoder *encoder = NULL;
	struct omap_encoder *omap_encoder;
	struct omap_overlay_manager_info info;
	int ret;

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

	omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL);
	if (!omap_encoder) {
		dev_err(dev->dev, "could not allocate encoder\n");
		goto fail;
	}

	omap_encoder->mgr = mgr;
	encoder = &omap_encoder->base;

	drm_encoder_init(dev, encoder, &omap_encoder_funcs,
			 DRM_MODE_ENCODER_TMDS);
	drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);

	mgr->get_manager_info(mgr, &info);

	/* TODO: fix hard-coded setup.. */
	info.default_color = 0x00000000;
	info.trans_key = 0x00000000;
	info.trans_key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
	info.trans_enabled = false;

	ret = mgr->set_manager_info(mgr, &info);
	if (ret) {
		dev_err(dev->dev, "could not set manager info\n");
		goto fail;
	}

	ret = mgr->apply(mgr);
	if (ret) {
		dev_err(dev->dev, "could not apply\n");
		goto fail;
	}

	return encoder;

fail:
	if (encoder) {
		omap_encoder_destroy(encoder);
	}

	return NULL;
}
