/*
 * drivers/staging/omapdrm/omap_crtc.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_mode.h"
#include "drm_crtc.h"
#include "drm_crtc_helper.h"

#define to_omap_crtc(x) container_of(x, struct omap_crtc, base)

struct omap_crtc {
	struct drm_crtc base;
	struct drm_plane *plane;
	const char *name;
	int id;

	/* if there is a pending flip, these will be non-null: */
	struct drm_pending_vblank_event *event;
	struct drm_framebuffer *old_fb;
};

static void omap_crtc_gamma_set(struct drm_crtc *crtc,
		u16 *red, u16 *green, u16 *blue, uint32_t start, uint32_t size)
{
	/* not supported.. at least not yet */
}

static void omap_crtc_destroy(struct drm_crtc *crtc)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	omap_crtc->plane->funcs->destroy(omap_crtc->plane);
	drm_crtc_cleanup(crtc);
	kfree(omap_crtc);
}

static void omap_crtc_dpms(struct drm_crtc *crtc, int mode)
{
	struct omap_drm_private *priv = crtc->dev->dev_private;
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	int i;

	WARN_ON(omap_plane_dpms(omap_crtc->plane, mode));

	for (i = 0; i < priv->num_planes; i++) {
		struct drm_plane *plane = priv->planes[i];
		if (plane->crtc == crtc)
			WARN_ON(omap_plane_dpms(plane, mode));
	}
}

static bool omap_crtc_mode_fixup(struct drm_crtc *crtc,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode)
{
	return true;
}

static int omap_crtc_mode_set(struct drm_crtc *crtc,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode,
		int x, int y,
		struct drm_framebuffer *old_fb)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_plane *plane = omap_crtc->plane;

	return omap_plane_mode_set(plane, crtc, crtc->fb,
			0, 0, mode->hdisplay, mode->vdisplay,
			x << 16, y << 16,
			mode->hdisplay << 16, mode->vdisplay << 16);
}

static void omap_crtc_prepare(struct drm_crtc *crtc)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	DBG("%s", omap_crtc->name);
	omap_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
}

static void omap_crtc_commit(struct drm_crtc *crtc)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	DBG("%s", omap_crtc->name);
	omap_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
}

static int omap_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
		struct drm_framebuffer *old_fb)
{
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_plane *plane = omap_crtc->plane;
	struct drm_display_mode *mode = &crtc->mode;

	return plane->funcs->update_plane(plane, crtc, crtc->fb,
			0, 0, mode->hdisplay, mode->vdisplay,
			x << 16, y << 16,
			mode->hdisplay << 16, mode->vdisplay << 16);
}

static void omap_crtc_load_lut(struct drm_crtc *crtc)
{
}

static void vblank_cb(void *arg)
{
	static uint32_t sequence = 0;
	struct drm_crtc *crtc = arg;
	struct drm_device *dev = crtc->dev;
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_pending_vblank_event *event = omap_crtc->event;
	unsigned long flags;
	struct timeval now;

	WARN_ON(!event);

	omap_crtc->event = NULL;

	/* wakeup userspace */
	if (event) {
		do_gettimeofday(&now);

		spin_lock_irqsave(&dev->event_lock, flags);
		/* TODO: we can't yet use the vblank time accounting,
		 * because omapdss lower layer is the one that knows
		 * the irq # and registers the handler, which more or
		 * less defeats how drm_irq works.. for now just fake
		 * the sequence number and use gettimeofday..
		 *
		event->event.sequence = drm_vblank_count_and_time(
				dev, omap_crtc->id, &now);
		 */
		event->event.sequence = sequence++;
		event->event.tv_sec = now.tv_sec;
		event->event.tv_usec = now.tv_usec;
		list_add_tail(&event->base.link,
				&event->base.file_priv->event_list);
		wake_up_interruptible(&event->base.file_priv->event_wait);
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}
}

static void page_flip_cb(void *arg)
{
	struct drm_crtc *crtc = arg;
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
	struct drm_framebuffer *old_fb = omap_crtc->old_fb;

	omap_crtc->old_fb = NULL;

	omap_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb);

	/* really we'd like to setup the callback atomically w/ setting the
	 * new scanout buffer to avoid getting stuck waiting an extra vblank
	 * cycle.. for now go for correctness and later figure out speed..
	 */
	omap_plane_on_endwin(omap_crtc->plane, vblank_cb, crtc);
}

static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
		 struct drm_framebuffer *fb,
		 struct drm_pending_vblank_event *event)
{
	struct drm_device *dev = crtc->dev;
	struct omap_crtc *omap_crtc = to_omap_crtc(crtc);

	DBG("%d -> %d", crtc->fb ? crtc->fb->base.id : -1, fb->base.id);

	if (omap_crtc->event) {
		dev_err(dev->dev, "already a pending flip\n");
		return -EINVAL;
	}

	omap_crtc->old_fb = crtc->fb;
	omap_crtc->event = event;
	crtc->fb = fb;

	omap_gem_op_async(omap_framebuffer_bo(fb, 0), OMAP_GEM_READ,
			page_flip_cb, crtc);

	return 0;
}

static const struct drm_crtc_funcs omap_crtc_funcs = {
	.gamma_set = omap_crtc_gamma_set,
	.set_config = drm_crtc_helper_set_config,
	.destroy = omap_crtc_destroy,
	.page_flip = omap_crtc_page_flip_locked,
};

static const struct drm_crtc_helper_funcs omap_crtc_helper_funcs = {
	.dpms = omap_crtc_dpms,
	.mode_fixup = omap_crtc_mode_fixup,
	.mode_set = omap_crtc_mode_set,
	.prepare = omap_crtc_prepare,
	.commit = omap_crtc_commit,
	.mode_set_base = omap_crtc_mode_set_base,
	.load_lut = omap_crtc_load_lut,
};

/* initialize crtc */
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
		struct omap_overlay *ovl, int id)
{
	struct drm_crtc *crtc = NULL;
	struct omap_crtc *omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);

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

	if (!omap_crtc) {
		dev_err(dev->dev, "could not allocate CRTC\n");
		goto fail;
	}

	crtc = &omap_crtc->base;

	omap_crtc->plane = omap_plane_init(dev, ovl, (1 << id), true);
	omap_crtc->plane->crtc = crtc;
	omap_crtc->name = ovl->name;
	omap_crtc->id = id;

	drm_crtc_init(dev, crtc, &omap_crtc_funcs);
	drm_crtc_helper_add(crtc, &omap_crtc_helper_funcs);

	return crtc;

fail:
	if (crtc) {
		omap_crtc_destroy(crtc);
	}
	return NULL;
}
