/*
 * drivers/staging/omapdrm/omap_plane.c
 *
 * Copyright (C) 2011 Texas Instruments
 * Author: Rob Clark <rob.clark@linaro.org>
 *
 * 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 <linux/kfifo.h>

#include "omap_drv.h"
#include "omap_dmm_tiler.h"

/* some hackery because omapdss has an 'enum omap_plane' (which would be
 * better named omap_plane_id).. and compiler seems unhappy about having
 * both a 'struct omap_plane' and 'enum omap_plane'
 */
#define omap_plane _omap_plane

/*
 * plane funcs
 */

struct callback {
	void (*fxn)(void *);
	void *arg;
};

#define to_omap_plane(x) container_of(x, struct omap_plane, base)

struct omap_plane {
	struct drm_plane base;
	struct omap_overlay *ovl;
	struct omap_overlay_info info;

	/* position/orientation of scanout within the fb: */
	struct omap_drm_window win;


	/* last fb that we pinned: */
	struct drm_framebuffer *pinned_fb;

	uint32_t nformats;
	uint32_t formats[32];

	/* for synchronizing access to unpins fifo */
	struct mutex unpin_mutex;

	/* set of bo's pending unpin until next END_WIN irq */
	DECLARE_KFIFO_PTR(unpin_fifo, struct drm_gem_object *);
	int num_unpins, pending_num_unpins;

	/* for deferred unpin when we need to wait for scanout complete irq */
	struct work_struct work;

	/* callback on next endwin irq */
	struct callback endwin;
};

/* map from ovl->id to the irq we are interested in for scanout-done */
static const uint32_t id2irq[] = {
		[OMAP_DSS_GFX]    = DISPC_IRQ_GFX_END_WIN,
		[OMAP_DSS_VIDEO1] = DISPC_IRQ_VID1_END_WIN,
		[OMAP_DSS_VIDEO2] = DISPC_IRQ_VID2_END_WIN,
		[OMAP_DSS_VIDEO3] = DISPC_IRQ_VID3_END_WIN,
};

static void dispc_isr(void *arg, uint32_t mask)
{
	struct drm_plane *plane = arg;
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_drm_private *priv = plane->dev->dev_private;

	omap_dispc_unregister_isr(dispc_isr, plane,
			id2irq[omap_plane->ovl->id]);

	queue_work(priv->wq, &omap_plane->work);
}

static void unpin_worker(struct work_struct *work)
{
	struct omap_plane *omap_plane =
			container_of(work, struct omap_plane, work);
	struct callback endwin;

	mutex_lock(&omap_plane->unpin_mutex);
	DBG("unpinning %d of %d", omap_plane->num_unpins,
			omap_plane->num_unpins + omap_plane->pending_num_unpins);
	while (omap_plane->num_unpins > 0) {
		struct drm_gem_object *bo = NULL;
		int ret = kfifo_get(&omap_plane->unpin_fifo, &bo);
		WARN_ON(!ret);
		omap_gem_put_paddr(bo);
		drm_gem_object_unreference_unlocked(bo);
		omap_plane->num_unpins--;
	}
	endwin = omap_plane->endwin;
	omap_plane->endwin.fxn = NULL;
	mutex_unlock(&omap_plane->unpin_mutex);

	if (endwin.fxn)
		endwin.fxn(endwin.arg);
}

static void install_irq(struct drm_plane *plane)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_overlay *ovl = omap_plane->ovl;
	int ret;

	ret = omap_dispc_register_isr(dispc_isr, plane, id2irq[ovl->id]);

	/*
	 * omapdss has upper limit on # of registered irq handlers,
	 * which we shouldn't hit.. but if we do the limit should
	 * be raised or bad things happen:
	 */
	WARN_ON(ret == -EBUSY);
}

/* push changes down to dss2 */
static int commit(struct drm_plane *plane)
{
	struct drm_device *dev = plane->dev;
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_overlay *ovl = omap_plane->ovl;
	struct omap_overlay_info *info = &omap_plane->info;
	int ret;

	DBG("%s", ovl->name);
	DBG("%dx%d -> %dx%d (%d)", info->width, info->height, info->out_width,
			info->out_height, info->screen_width);
	DBG("%d,%d %08x %08x", info->pos_x, info->pos_y,
			info->paddr, info->p_uv_addr);

	/* NOTE: do we want to do this at all here, or just wait
	 * for dpms(ON) since other CRTC's may not have their mode
	 * set yet, so fb dimensions may still change..
	 */
	ret = ovl->set_overlay_info(ovl, info);
	if (ret) {
		dev_err(dev->dev, "could not set overlay info\n");
		return ret;
	}

	mutex_lock(&omap_plane->unpin_mutex);
	omap_plane->num_unpins += omap_plane->pending_num_unpins;
	omap_plane->pending_num_unpins = 0;
	mutex_unlock(&omap_plane->unpin_mutex);

	/* our encoder doesn't necessarily get a commit() after this, in
	 * particular in the dpms() and mode_set_base() cases, so force the
	 * manager to update:
	 *
	 * could this be in the encoder somehow?
	 */
	if (ovl->manager) {
		ret = ovl->manager->apply(ovl->manager);
		if (ret) {
			dev_err(dev->dev, "could not apply settings\n");
			return ret;
		}

		/*
		 * NOTE: really this should be atomic w/ mgr->apply() but
		 * omapdss does not expose such an API
		 */
		if (omap_plane->num_unpins > 0)
			install_irq(plane);

	} else {
		struct omap_drm_private *priv = dev->dev_private;
		queue_work(priv->wq, &omap_plane->work);
	}


	if (ovl->is_enabled(ovl)) {
		omap_framebuffer_flush(plane->fb, info->pos_x, info->pos_y,
				info->out_width, info->out_height);
	}

	return 0;
}

/* when CRTC that we are attached to has potentially changed, this checks
 * if we are attached to proper manager, and if necessary updates.
 */
static void update_manager(struct drm_plane *plane)
{
	struct omap_drm_private *priv = plane->dev->dev_private;
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_overlay *ovl = omap_plane->ovl;
	struct omap_overlay_manager *mgr = NULL;
	int i;

	if (plane->crtc) {
		for (i = 0; i < priv->num_encoders; i++) {
			struct drm_encoder *encoder = priv->encoders[i];
			if (encoder->crtc == plane->crtc) {
				mgr = omap_encoder_get_manager(encoder);
				break;
			}
		}
	}

	if (ovl->manager != mgr) {
		bool enabled = ovl->is_enabled(ovl);

		/* don't switch things around with enabled overlays: */
		if (enabled)
			omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);

		if (ovl->manager) {
			DBG("disconnecting %s from %s", ovl->name,
					ovl->manager->name);
			ovl->unset_manager(ovl);
		}

		if (mgr) {
			DBG("connecting %s to %s", ovl->name, mgr->name);
			ovl->set_manager(ovl, mgr);
		}

		if (enabled && mgr)
			omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
	}
}

static void unpin(void *arg, struct drm_gem_object *bo)
{
	struct drm_plane *plane = arg;
	struct omap_plane *omap_plane = to_omap_plane(plane);

	if (kfifo_put(&omap_plane->unpin_fifo,
			(const struct drm_gem_object **)&bo)) {
		omap_plane->pending_num_unpins++;
		/* also hold a ref so it isn't free'd while pinned */
		drm_gem_object_reference(bo);
	} else {
		dev_err(plane->dev->dev, "unpin fifo full!\n");
		omap_gem_put_paddr(bo);
	}
}

/* update which fb (if any) is pinned for scanout */
static int update_pin(struct drm_plane *plane, struct drm_framebuffer *fb)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct drm_framebuffer *pinned_fb = omap_plane->pinned_fb;

	if (pinned_fb != fb) {
		int ret;

		DBG("%p -> %p", pinned_fb, fb);

		mutex_lock(&omap_plane->unpin_mutex);
		ret = omap_framebuffer_replace(pinned_fb, fb, plane, unpin);
		mutex_unlock(&omap_plane->unpin_mutex);

		if (ret) {
			dev_err(plane->dev->dev, "could not swap %p -> %p\n",
					omap_plane->pinned_fb, fb);
			omap_plane->pinned_fb = NULL;
			return ret;
		}

		omap_plane->pinned_fb = fb;
	}

	return 0;
}

/* update parameters that are dependent on the framebuffer dimensions and
 * position within the fb that this plane scans out from. This is called
 * when framebuffer or x,y base may have changed.
 */
static void update_scanout(struct drm_plane *plane)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_overlay_info *info = &omap_plane->info;
	struct omap_drm_window *win = &omap_plane->win;
	int ret;

	ret = update_pin(plane, plane->fb);
	if (ret) {
		dev_err(plane->dev->dev,
			"could not pin fb: %d\n", ret);
		omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
		return;
	}

	omap_framebuffer_update_scanout(plane->fb, win, info);

	DBG("%s: %d,%d: %08x %08x (%d)", omap_plane->ovl->name,
			win->src_x, win->src_y,
			(u32)info->paddr, (u32)info->p_uv_addr,
			info->screen_width);
}

int omap_plane_mode_set(struct drm_plane *plane,
		struct drm_crtc *crtc, struct drm_framebuffer *fb,
		int crtc_x, int crtc_y,
		unsigned int crtc_w, unsigned int crtc_h,
		uint32_t src_x, uint32_t src_y,
		uint32_t src_w, uint32_t src_h)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_drm_window *win = &omap_plane->win;

	win->crtc_x = crtc_x;
	win->crtc_y = crtc_y;
	win->crtc_w = crtc_w;
	win->crtc_h = crtc_h;

	/* src values are in Q16 fixed point, convert to integer: */
	win->src_x = src_x >> 16;
	win->src_y = src_y >> 16;
	win->src_w = src_w >> 16;
	win->src_h = src_h >> 16;

	/* note: this is done after this fxn returns.. but if we need
	 * to do a commit/update_scanout, etc before this returns we
	 * need the current value.
	 */
	plane->fb = fb;
	plane->crtc = crtc;

	update_scanout(plane);
	update_manager(plane);

	return 0;
}

static int omap_plane_update(struct drm_plane *plane,
		struct drm_crtc *crtc, struct drm_framebuffer *fb,
		int crtc_x, int crtc_y,
		unsigned int crtc_w, unsigned int crtc_h,
		uint32_t src_x, uint32_t src_y,
		uint32_t src_w, uint32_t src_h)
{
	omap_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h,
			src_x, src_y, src_w, src_h);
	return omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
}

static int omap_plane_disable(struct drm_plane *plane)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	omap_plane->win.rotation = BIT(DRM_ROTATE_0);
	return omap_plane_dpms(plane, DRM_MODE_DPMS_OFF);
}

static void omap_plane_destroy(struct drm_plane *plane)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	DBG("%s", omap_plane->ovl->name);
	omap_plane_disable(plane);
	drm_plane_cleanup(plane);
	WARN_ON(omap_plane->pending_num_unpins + omap_plane->num_unpins > 0);
	kfifo_free(&omap_plane->unpin_fifo);
	kfree(omap_plane);
}

int omap_plane_dpms(struct drm_plane *plane, int mode)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_overlay *ovl = omap_plane->ovl;
	int r;

	DBG("%s: %d", omap_plane->ovl->name, mode);

	if (mode == DRM_MODE_DPMS_ON) {
		update_scanout(plane);
		r = commit(plane);
		if (!r)
			r = ovl->enable(ovl);
	} else {
		struct omap_drm_private *priv = plane->dev->dev_private;
		r = ovl->disable(ovl);
		update_pin(plane, NULL);
		queue_work(priv->wq, &omap_plane->work);
	}

	return r;
}

void omap_plane_on_endwin(struct drm_plane *plane,
		void (*fxn)(void *), void *arg)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);

	mutex_lock(&omap_plane->unpin_mutex);
	omap_plane->endwin.fxn = fxn;
	omap_plane->endwin.arg = arg;
	mutex_unlock(&omap_plane->unpin_mutex);

	install_irq(plane);
}

/* helper to install properties which are common to planes and crtcs */
void omap_plane_install_properties(struct drm_plane *plane,
		struct drm_mode_object *obj)
{
	struct drm_device *dev = plane->dev;
	struct omap_drm_private *priv = dev->dev_private;
	struct drm_property *prop;

	prop = priv->rotation_prop;
	if (!prop) {
		const struct drm_prop_enum_list props[] = {
				{ DRM_ROTATE_0,   "rotate-0" },
				{ DRM_ROTATE_90,  "rotate-90" },
				{ DRM_ROTATE_180, "rotate-180" },
				{ DRM_ROTATE_270, "rotate-270" },
				{ DRM_REFLECT_X,  "reflect-x" },
				{ DRM_REFLECT_Y,  "reflect-y" },
		};
		prop = drm_property_create_bitmask(dev, 0, "rotation",
				props, ARRAY_SIZE(props));
		if (prop == NULL)
			return;
		priv->rotation_prop = prop;
	}
	drm_object_attach_property(obj, prop, 0);

        prop = priv->zorder_prop;
        if (!prop) {
		prop = drm_property_create_range(dev, 0, "zorder", 0, 3);
		if (prop == NULL)
			return;
		priv->zorder_prop = prop;
	}
	drm_object_attach_property(obj, prop, 0);
}

int omap_plane_set_property(struct drm_plane *plane,
		struct drm_property *property, uint64_t val)
{
	struct omap_plane *omap_plane = to_omap_plane(plane);
	struct omap_drm_private *priv = plane->dev->dev_private;
	int ret = -EINVAL;

	if (property == priv->rotation_prop) {
		struct omap_overlay *ovl = omap_plane->ovl;

		DBG("%s: rotation: %02x", ovl->name, (uint32_t)val);
		omap_plane->win.rotation = val;

		if (ovl->is_enabled(ovl))
			ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
		else
			ret = 0;
	} else if (property == priv->zorder_prop) {
		struct omap_overlay *ovl = omap_plane->ovl;

		DBG("%s: zorder: %d", ovl->name, (uint32_t)val);
		omap_plane->info.zorder = val;

		if (ovl->is_enabled(ovl))
			ret = omap_plane_dpms(plane, DRM_MODE_DPMS_ON);
		else
			ret = 0;
	}

	return ret;
}

static const struct drm_plane_funcs omap_plane_funcs = {
		.update_plane = omap_plane_update,
		.disable_plane = omap_plane_disable,
		.destroy = omap_plane_destroy,
		.set_property = omap_plane_set_property,
};

/* initialize plane */
struct drm_plane *omap_plane_init(struct drm_device *dev,
		struct omap_overlay *ovl, unsigned int possible_crtcs,
		bool priv)
{
	struct drm_plane *plane = NULL;
	struct omap_plane *omap_plane;
	int ret;

	DBG("%s: possible_crtcs=%08x, priv=%d", ovl->name,
			possible_crtcs, priv);

	/* friendly reminder to update table for future hw: */
	WARN_ON(ovl->id >= ARRAY_SIZE(id2irq));

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

	mutex_init(&omap_plane->unpin_mutex);

	ret = kfifo_alloc(&omap_plane->unpin_fifo, 16, GFP_KERNEL);
	if (ret) {
		dev_err(dev->dev, "could not allocate unpin FIFO\n");
		goto fail;
	}

	INIT_WORK(&omap_plane->work, unpin_worker);

	omap_plane->nformats = omap_framebuffer_get_formats(
			omap_plane->formats, ARRAY_SIZE(omap_plane->formats),
			ovl->supported_modes);
	omap_plane->ovl = ovl;
	plane = &omap_plane->base;

	drm_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs,
			omap_plane->formats, omap_plane->nformats, priv);

	omap_plane_install_properties(plane, &plane->base);

	/* get our starting configuration, set defaults for parameters
	 * we don't currently use, etc:
	 */
	ovl->get_overlay_info(ovl, &omap_plane->info);
	omap_plane->info.rotation_type = OMAP_DSS_ROT_DMA;
	omap_plane->info.rotation = OMAP_DSS_ROT_0;
	omap_plane->info.global_alpha = 0xff;
	omap_plane->info.mirror = 0;

	/* Set defaults depending on whether we are a CRTC or overlay
	 * layer.
	 * TODO add ioctl to give userspace an API to change this.. this
	 * will come in a subsequent patch.
	 */
	if (priv)
		omap_plane->info.zorder = 0;
	else
		omap_plane->info.zorder = ovl->id;

	update_manager(plane);

	return plane;

fail:
	if (plane) {
		omap_plane_destroy(plane);
	}
	return NULL;
}
