/*
 * Copyright (C) STMicroelectronics SA 2014
 * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
 *          Fabien Dessenne <fabien.dessenne@st.com>
 *          for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <drm/drmP.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_fb_cma_helper.h>

#include "sti_compositor.h"
#include "sti_cursor.h"
#include "sti_gdp.h"
#include "sti_hqvdp.h"
#include "sti_layer.h"
#include "sti_vid.h"

const char *sti_layer_to_str(struct sti_layer *layer)
{
	switch (layer->desc) {
	case STI_GDP_0:
		return "GDP0";
	case STI_GDP_1:
		return "GDP1";
	case STI_GDP_2:
		return "GDP2";
	case STI_GDP_3:
		return "GDP3";
	case STI_VID_0:
		return "VID0";
	case STI_VID_1:
		return "VID1";
	case STI_CURSOR:
		return "CURSOR";
	case STI_HQVDP_0:
		return "HQVDP0";
	default:
		return "<UNKNOWN LAYER>";
	}
}
EXPORT_SYMBOL(sti_layer_to_str);

struct sti_layer *sti_layer_create(struct device *dev, int desc,
				   void __iomem *baseaddr)
{

	struct sti_layer *layer = NULL;

	switch (desc & STI_LAYER_TYPE_MASK) {
	case STI_GDP:
		layer = sti_gdp_create(dev, desc);
		break;
	case STI_VID:
		layer = sti_vid_create(dev);
		break;
	case STI_CUR:
		layer = sti_cursor_create(dev);
		break;
	case STI_VDP:
		layer = sti_hqvdp_create(dev);
		break;
	}

	if (!layer) {
		DRM_ERROR("Failed to create layer\n");
		return NULL;
	}

	layer->desc = desc;
	layer->dev = dev;
	layer->regs = baseaddr;

	layer->ops->init(layer);

	DRM_DEBUG_DRIVER("%s created\n", sti_layer_to_str(layer));

	return layer;
}
EXPORT_SYMBOL(sti_layer_create);

int sti_layer_prepare(struct sti_layer *layer,
		      struct drm_crtc *crtc,
		      struct drm_framebuffer *fb,
		      struct drm_display_mode *mode, int mixer_id,
		      int dest_x, int dest_y, int dest_w, int dest_h,
		      int src_x, int src_y, int src_w, int src_h)
{
	int ret;
	unsigned int i;
	struct drm_gem_cma_object *cma_obj;

	if (!layer || !fb || !mode) {
		DRM_ERROR("Null fb, layer or mode\n");
		return 1;
	}

	cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
	if (!cma_obj) {
		DRM_ERROR("Can't get CMA GEM object for fb\n");
		return 1;
	}

	layer->crtc = crtc;
	layer->fb = fb;
	layer->mode = mode;
	layer->mixer_id = mixer_id;
	layer->dst_x = dest_x;
	layer->dst_y = dest_y;
	layer->dst_w = clamp_val(dest_w, 0, mode->crtc_hdisplay - dest_x);
	layer->dst_h = clamp_val(dest_h, 0, mode->crtc_vdisplay - dest_y);
	layer->src_x = src_x;
	layer->src_y = src_y;
	layer->src_w = src_w;
	layer->src_h = src_h;
	layer->format = fb->pixel_format;
	layer->vaddr = cma_obj->vaddr;
	layer->paddr = cma_obj->paddr;
	for (i = 0; i < 4; i++) {
		layer->pitches[i] = fb->pitches[i];
		layer->offsets[i] = fb->offsets[i];
	}

	DRM_DEBUG_DRIVER("%s is associated with mixer_id %d\n",
			 sti_layer_to_str(layer),
			 layer->mixer_id);
	DRM_DEBUG_DRIVER("%s dst=(%dx%d)@(%d,%d) - src=(%dx%d)@(%d,%d)\n",
			 sti_layer_to_str(layer),
			 layer->dst_w, layer->dst_h, layer->dst_x, layer->dst_y,
			 layer->src_w, layer->src_h, layer->src_x,
			 layer->src_y);

	DRM_DEBUG_DRIVER("drm FB:%d format:%.4s phys@:0x%lx\n", fb->base.id,
			 (char *)&layer->format, (unsigned long)layer->paddr);

	if (!layer->ops->prepare)
		goto err_no_prepare;

	ret = layer->ops->prepare(layer, !layer->enabled);
	if (!ret)
		layer->enabled = true;

	return ret;

err_no_prepare:
	DRM_ERROR("Cannot prepare\n");
	return 1;
}

int sti_layer_commit(struct sti_layer *layer)
{
	if (!layer)
		return 1;

	if (!layer->ops->commit)
		goto err_no_commit;

	return layer->ops->commit(layer);

err_no_commit:
	DRM_ERROR("Cannot commit\n");
	return 1;
}

int sti_layer_disable(struct sti_layer *layer)
{
	int ret;

	DRM_DEBUG_DRIVER("%s\n", sti_layer_to_str(layer));
	if (!layer)
		return 1;

	if (!layer->enabled)
		return 0;

	if (!layer->ops->disable)
		goto err_no_disable;

	ret = layer->ops->disable(layer);
	if (!ret)
		layer->enabled = false;
	else
		DRM_ERROR("Disable failed\n");

	return ret;

err_no_disable:
	DRM_ERROR("Cannot disable\n");
	return 1;
}

const uint32_t *sti_layer_get_formats(struct sti_layer *layer)
{
	if (!layer)
		return NULL;

	if (!layer->ops->get_formats)
		return NULL;

	return layer->ops->get_formats(layer);
}

unsigned int sti_layer_get_nb_formats(struct sti_layer *layer)
{
	if (!layer)
		return 0;

	if (!layer->ops->get_nb_formats)
		return 0;

	return layer->ops->get_nb_formats(layer);
}
