/*
 * Copyright (C) 2014 Free Electrons
 * Copyright (C) 2014 Atmel
 *
 * Author: Boris BREZILLON <boris.brezillon@free-electrons.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 "atmel_hlcdc_dc.h"

#define SUBPIXEL_MASK			0xffff

static uint32_t rgb_formats[] = {
	DRM_FORMAT_XRGB4444,
	DRM_FORMAT_ARGB4444,
	DRM_FORMAT_RGBA4444,
	DRM_FORMAT_ARGB1555,
	DRM_FORMAT_RGB565,
	DRM_FORMAT_RGB888,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_RGBA8888,
};

struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = {
	.formats = rgb_formats,
	.nformats = ARRAY_SIZE(rgb_formats),
};

static uint32_t rgb_and_yuv_formats[] = {
	DRM_FORMAT_XRGB4444,
	DRM_FORMAT_ARGB4444,
	DRM_FORMAT_RGBA4444,
	DRM_FORMAT_ARGB1555,
	DRM_FORMAT_RGB565,
	DRM_FORMAT_RGB888,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_RGBA8888,
	DRM_FORMAT_AYUV,
	DRM_FORMAT_YUYV,
	DRM_FORMAT_UYVY,
	DRM_FORMAT_YVYU,
	DRM_FORMAT_VYUY,
	DRM_FORMAT_NV21,
	DRM_FORMAT_NV61,
	DRM_FORMAT_YUV422,
	DRM_FORMAT_YUV420,
};

struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = {
	.formats = rgb_and_yuv_formats,
	.nformats = ARRAY_SIZE(rgb_and_yuv_formats),
};

static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
{
	switch (format) {
	case DRM_FORMAT_XRGB4444:
		*mode = ATMEL_HLCDC_XRGB4444_MODE;
		break;
	case DRM_FORMAT_ARGB4444:
		*mode = ATMEL_HLCDC_ARGB4444_MODE;
		break;
	case DRM_FORMAT_RGBA4444:
		*mode = ATMEL_HLCDC_RGBA4444_MODE;
		break;
	case DRM_FORMAT_RGB565:
		*mode = ATMEL_HLCDC_RGB565_MODE;
		break;
	case DRM_FORMAT_RGB888:
		*mode = ATMEL_HLCDC_RGB888_MODE;
		break;
	case DRM_FORMAT_ARGB1555:
		*mode = ATMEL_HLCDC_ARGB1555_MODE;
		break;
	case DRM_FORMAT_XRGB8888:
		*mode = ATMEL_HLCDC_XRGB8888_MODE;
		break;
	case DRM_FORMAT_ARGB8888:
		*mode = ATMEL_HLCDC_ARGB8888_MODE;
		break;
	case DRM_FORMAT_RGBA8888:
		*mode = ATMEL_HLCDC_RGBA8888_MODE;
		break;
	case DRM_FORMAT_AYUV:
		*mode = ATMEL_HLCDC_AYUV_MODE;
		break;
	case DRM_FORMAT_YUYV:
		*mode = ATMEL_HLCDC_YUYV_MODE;
		break;
	case DRM_FORMAT_UYVY:
		*mode = ATMEL_HLCDC_UYVY_MODE;
		break;
	case DRM_FORMAT_YVYU:
		*mode = ATMEL_HLCDC_YVYU_MODE;
		break;
	case DRM_FORMAT_VYUY:
		*mode = ATMEL_HLCDC_VYUY_MODE;
		break;
	case DRM_FORMAT_NV21:
		*mode = ATMEL_HLCDC_NV21_MODE;
		break;
	case DRM_FORMAT_NV61:
		*mode = ATMEL_HLCDC_NV61_MODE;
		break;
	case DRM_FORMAT_YUV420:
		*mode = ATMEL_HLCDC_YUV420_MODE;
		break;
	case DRM_FORMAT_YUV422:
		*mode = ATMEL_HLCDC_YUV422_MODE;
		break;
	default:
		return -ENOTSUPP;
	}

	return 0;
}

static bool atmel_hlcdc_format_embedds_alpha(u32 format)
{
	int i;

	for (i = 0; i < sizeof(format); i++) {
		char tmp = (format >> (8 * i)) & 0xff;

		if (tmp == 'A')
			return true;
	}

	return false;
}

static u32 heo_downscaling_xcoef[] = {
	0x11343311,
	0x000000f7,
	0x1635300c,
	0x000000f9,
	0x1b362c08,
	0x000000fb,
	0x1f372804,
	0x000000fe,
	0x24382400,
	0x00000000,
	0x28371ffe,
	0x00000004,
	0x2c361bfb,
	0x00000008,
	0x303516f9,
	0x0000000c,
};

static u32 heo_downscaling_ycoef[] = {
	0x00123737,
	0x00173732,
	0x001b382d,
	0x001f3928,
	0x00243824,
	0x0028391f,
	0x002d381b,
	0x00323717,
};

static u32 heo_upscaling_xcoef[] = {
	0xf74949f7,
	0x00000000,
	0xf55f33fb,
	0x000000fe,
	0xf5701efe,
	0x000000ff,
	0xf87c0dff,
	0x00000000,
	0x00800000,
	0x00000000,
	0x0d7cf800,
	0x000000ff,
	0x1e70f5ff,
	0x000000fe,
	0x335ff5fe,
	0x000000fb,
};

static u32 heo_upscaling_ycoef[] = {
	0x00004040,
	0x00075920,
	0x00056f0c,
	0x00027b03,
	0x00008000,
	0x00037b02,
	0x000c6f05,
	0x00205907,
};

static void
atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
				struct atmel_hlcdc_plane_update_req *req)
{
	const struct atmel_hlcdc_layer_cfg_layout *layout =
						&plane->layer.desc->layout;

	if (layout->size)
		atmel_hlcdc_layer_update_cfg(&plane->layer,
					     layout->size,
					     0xffffffff,
					     (req->crtc_w - 1) |
					     ((req->crtc_h - 1) << 16));

	if (layout->memsize)
		atmel_hlcdc_layer_update_cfg(&plane->layer,
					     layout->memsize,
					     0xffffffff,
					     (req->src_w - 1) |
					     ((req->src_h - 1) << 16));

	if (layout->pos)
		atmel_hlcdc_layer_update_cfg(&plane->layer,
					     layout->pos,
					     0xffffffff,
					     req->crtc_x |
					     (req->crtc_y  << 16));

	/* TODO: rework the rescaling part */
	if (req->crtc_w != req->src_w || req->crtc_h != req->src_h) {
		u32 factor_reg = 0;

		if (req->crtc_w != req->src_w) {
			int i;
			u32 factor;
			u32 *coeff_tab = heo_upscaling_xcoef;
			u32 max_memsize;

			if (req->crtc_w < req->src_w)
				coeff_tab = heo_downscaling_xcoef;
			for (i = 0; i < ARRAY_SIZE(heo_upscaling_xcoef); i++)
				atmel_hlcdc_layer_update_cfg(&plane->layer,
							     17 + i,
							     0xffffffff,
							     coeff_tab[i]);
			factor = ((8 * 256 * req->src_w) - (256 * 4)) /
				 req->crtc_w;
			factor++;
			max_memsize = ((factor * req->crtc_w) + (256 * 4)) /
				      2048;
			if (max_memsize > req->src_w)
				factor--;
			factor_reg |= factor | 0x80000000;
		}

		if (req->crtc_h != req->src_h) {
			int i;
			u32 factor;
			u32 *coeff_tab = heo_upscaling_ycoef;
			u32 max_memsize;

			if (req->crtc_w < req->src_w)
				coeff_tab = heo_downscaling_ycoef;
			for (i = 0; i < ARRAY_SIZE(heo_upscaling_ycoef); i++)
				atmel_hlcdc_layer_update_cfg(&plane->layer,
							     33 + i,
							     0xffffffff,
							     coeff_tab[i]);
			factor = ((8 * 256 * req->src_w) - (256 * 4)) /
				 req->crtc_w;
			factor++;
			max_memsize = ((factor * req->crtc_w) + (256 * 4)) /
				      2048;
			if (max_memsize > req->src_w)
				factor--;
			factor_reg |= (factor << 16) | 0x80000000;
		}

		atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
					     factor_reg);
	}
}

static void
atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
				struct atmel_hlcdc_plane_update_req *req)
{
	const struct atmel_hlcdc_layer_cfg_layout *layout =
						&plane->layer.desc->layout;
	unsigned int cfg = ATMEL_HLCDC_LAYER_DMA;

	if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
		cfg |= ATMEL_HLCDC_LAYER_OVR | ATMEL_HLCDC_LAYER_ITER2BL |
		       ATMEL_HLCDC_LAYER_ITER;

		if (atmel_hlcdc_format_embedds_alpha(req->fb->pixel_format))
			cfg |= ATMEL_HLCDC_LAYER_LAEN;
		else
			cfg |= ATMEL_HLCDC_LAYER_GAEN;
	}

	atmel_hlcdc_layer_update_cfg(&plane->layer,
				     ATMEL_HLCDC_LAYER_DMA_CFG_ID,
				     ATMEL_HLCDC_LAYER_DMA_BLEN_MASK,
				     ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16);

	atmel_hlcdc_layer_update_cfg(&plane->layer, layout->general_config,
				     ATMEL_HLCDC_LAYER_ITER2BL |
				     ATMEL_HLCDC_LAYER_ITER |
				     ATMEL_HLCDC_LAYER_GAEN |
				     ATMEL_HLCDC_LAYER_LAEN |
				     ATMEL_HLCDC_LAYER_OVR |
				     ATMEL_HLCDC_LAYER_DMA, cfg);
}

static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
				struct atmel_hlcdc_plane_update_req *req)
{
	u32 cfg;
	int ret;

	ret = atmel_hlcdc_format_to_plane_mode(req->fb->pixel_format, &cfg);
	if (ret)
		return;

	if ((req->fb->pixel_format == DRM_FORMAT_YUV422 ||
	     req->fb->pixel_format == DRM_FORMAT_NV61) &&
	    (plane->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))))
		cfg |= ATMEL_HLCDC_YUV422ROT;

	atmel_hlcdc_layer_update_cfg(&plane->layer,
				     ATMEL_HLCDC_LAYER_FORMAT_CFG_ID,
				     0xffffffff,
				     cfg);

	/*
	 * Rotation optimization is not working on RGB888 (rotation is still
	 * working but without any optimization).
	 */
	if (req->fb->pixel_format == DRM_FORMAT_RGB888)
		cfg = ATMEL_HLCDC_LAYER_DMA_ROTDIS;
	else
		cfg = 0;

	atmel_hlcdc_layer_update_cfg(&plane->layer,
				     ATMEL_HLCDC_LAYER_DMA_CFG_ID,
				     ATMEL_HLCDC_LAYER_DMA_ROTDIS, cfg);
}

static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
				struct atmel_hlcdc_plane_update_req *req)
{
	struct atmel_hlcdc_layer *layer = &plane->layer;
	const struct atmel_hlcdc_layer_cfg_layout *layout =
							&layer->desc->layout;
	int i;

	atmel_hlcdc_layer_update_set_fb(&plane->layer, req->fb, req->offsets);

	for (i = 0; i < req->nplanes; i++) {
		if (layout->xstride[i]) {
			atmel_hlcdc_layer_update_cfg(&plane->layer,
						layout->xstride[i],
						0xffffffff,
						req->xstride[i]);
		}

		if (layout->pstride[i]) {
			atmel_hlcdc_layer_update_cfg(&plane->layer,
						layout->pstride[i],
						0xffffffff,
						req->pstride[i]);
		}
	}
}

static int atmel_hlcdc_plane_check_update_req(struct drm_plane *p,
				struct atmel_hlcdc_plane_update_req *req,
				const struct drm_display_mode *mode)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
	const struct atmel_hlcdc_layer_cfg_layout *layout =
						&plane->layer.desc->layout;

	if (!layout->size &&
	    (mode->hdisplay != req->crtc_w ||
	     mode->vdisplay != req->crtc_h))
		return -EINVAL;

	if (plane->layer.desc->max_height &&
	    req->crtc_h > plane->layer.desc->max_height)
		return -EINVAL;

	if (plane->layer.desc->max_width &&
	    req->crtc_w > plane->layer.desc->max_width)
		return -EINVAL;

	if ((req->crtc_h != req->src_h || req->crtc_w != req->src_w) &&
	    (!layout->memsize ||
	     atmel_hlcdc_format_embedds_alpha(req->fb->pixel_format)))
		return -EINVAL;

	if (req->crtc_x < 0 || req->crtc_y < 0)
		return -EINVAL;

	if (req->crtc_w + req->crtc_x > mode->hdisplay ||
	    req->crtc_h + req->crtc_y > mode->vdisplay)
		return -EINVAL;

	return 0;
}

int atmel_hlcdc_plane_prepare_update_req(struct drm_plane *p,
				struct atmel_hlcdc_plane_update_req *req,
				const struct drm_display_mode *mode)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
	unsigned int patched_crtc_w;
	unsigned int patched_crtc_h;
	unsigned int patched_src_w;
	unsigned int patched_src_h;
	unsigned int tmp;
	int x_offset = 0;
	int y_offset = 0;
	int hsub = 1;
	int vsub = 1;
	int i;

	if ((req->src_x | req->src_y | req->src_w | req->src_h) &
	    SUBPIXEL_MASK)
		return -EINVAL;

	req->src_x >>= 16;
	req->src_y >>= 16;
	req->src_w >>= 16;
	req->src_h >>= 16;

	req->nplanes = drm_format_num_planes(req->fb->pixel_format);
	if (req->nplanes > ATMEL_HLCDC_MAX_PLANES)
		return -EINVAL;

	/*
	 * Swap width and size in case of 90 or 270 degrees rotation
	 */
	if (plane->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) {
		tmp = req->crtc_w;
		req->crtc_w = req->crtc_h;
		req->crtc_h = tmp;
		tmp = req->src_w;
		req->src_w = req->src_h;
		req->src_h = tmp;
	}

	if (req->crtc_x + req->crtc_w > mode->hdisplay)
		patched_crtc_w = mode->hdisplay - req->crtc_x;
	else
		patched_crtc_w = req->crtc_w;

	if (req->crtc_x < 0) {
		patched_crtc_w += req->crtc_x;
		x_offset = -req->crtc_x;
		req->crtc_x = 0;
	}

	if (req->crtc_y + req->crtc_h > mode->vdisplay)
		patched_crtc_h = mode->vdisplay - req->crtc_y;
	else
		patched_crtc_h = req->crtc_h;

	if (req->crtc_y < 0) {
		patched_crtc_h += req->crtc_y;
		y_offset = -req->crtc_y;
		req->crtc_y = 0;
	}

	patched_src_w = DIV_ROUND_CLOSEST(patched_crtc_w * req->src_w,
					  req->crtc_w);
	patched_src_h = DIV_ROUND_CLOSEST(patched_crtc_h * req->src_h,
					  req->crtc_h);

	hsub = drm_format_horz_chroma_subsampling(req->fb->pixel_format);
	vsub = drm_format_vert_chroma_subsampling(req->fb->pixel_format);

	for (i = 0; i < req->nplanes; i++) {
		unsigned int offset = 0;
		int xdiv = i ? hsub : 1;
		int ydiv = i ? vsub : 1;

		req->bpp[i] = drm_format_plane_cpp(req->fb->pixel_format, i);
		if (!req->bpp[i])
			return -EINVAL;

		switch (plane->rotation & 0xf) {
		case BIT(DRM_ROTATE_90):
			offset = ((y_offset + req->src_y + patched_src_w - 1) /
				  ydiv) * req->fb->pitches[i];
			offset += ((x_offset + req->src_x) / xdiv) *
				  req->bpp[i];
			req->xstride[i] = ((patched_src_w - 1) / ydiv) *
					  req->fb->pitches[i];
			req->pstride[i] = -req->fb->pitches[i] - req->bpp[i];
			break;
		case BIT(DRM_ROTATE_180):
			offset = ((y_offset + req->src_y + patched_src_h - 1) /
				  ydiv) * req->fb->pitches[i];
			offset += ((x_offset + req->src_x + patched_src_w - 1) /
				   xdiv) * req->bpp[i];
			req->xstride[i] = ((((patched_src_w - 1) / xdiv) - 1) *
					   req->bpp[i]) - req->fb->pitches[i];
			req->pstride[i] = -2 * req->bpp[i];
			break;
		case BIT(DRM_ROTATE_270):
			offset = ((y_offset + req->src_y) / ydiv) *
				 req->fb->pitches[i];
			offset += ((x_offset + req->src_x + patched_src_h - 1) /
				   xdiv) * req->bpp[i];
			req->xstride[i] = -(((patched_src_w - 1) / ydiv) *
					    req->fb->pitches[i]) -
					  (2 * req->bpp[i]);
			req->pstride[i] = req->fb->pitches[i] - req->bpp[i];
			break;
		case BIT(DRM_ROTATE_0):
		default:
			offset = ((y_offset + req->src_y) / ydiv) *
				 req->fb->pitches[i];
			offset += ((x_offset + req->src_x) / xdiv) *
				  req->bpp[i];
			req->xstride[i] = req->fb->pitches[i] -
					  ((patched_src_w / xdiv) *
					   req->bpp[i]);
			req->pstride[i] = 0;
			break;
		}

		req->offsets[i] = offset + req->fb->offsets[i];
	}

	req->src_w = patched_src_w;
	req->src_h = patched_src_h;
	req->crtc_w = patched_crtc_w;
	req->crtc_h = patched_crtc_h;

	return atmel_hlcdc_plane_check_update_req(p, req, mode);
}

int atmel_hlcdc_plane_apply_update_req(struct drm_plane *p,
				struct atmel_hlcdc_plane_update_req *req)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
	int ret;

	ret = atmel_hlcdc_layer_update_start(&plane->layer);
	if (ret)
		return ret;

	atmel_hlcdc_plane_update_pos_and_size(plane, req);
	atmel_hlcdc_plane_update_general_settings(plane, req);
	atmel_hlcdc_plane_update_format(plane, req);
	atmel_hlcdc_plane_update_buffers(plane, req);

	atmel_hlcdc_layer_update_commit(&plane->layer);

	return 0;
}

int atmel_hlcdc_plane_update_with_mode(struct drm_plane *p,
				       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,
				       const struct drm_display_mode *mode)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
	struct atmel_hlcdc_plane_update_req req;
	int ret = 0;

	memset(&req, 0, sizeof(req));
	req.crtc_x = crtc_x;
	req.crtc_y = crtc_y;
	req.crtc_w = crtc_w;
	req.crtc_h = crtc_h;
	req.src_x = src_x;
	req.src_y = src_y;
	req.src_w = src_w;
	req.src_h = src_h;
	req.fb = fb;

	ret = atmel_hlcdc_plane_prepare_update_req(&plane->base, &req, mode);
	if (ret)
		return ret;

	if (!req.crtc_h || !req.crtc_w)
		return atmel_hlcdc_layer_disable(&plane->layer);

	return atmel_hlcdc_plane_apply_update_req(&plane->base, &req);
}

static int atmel_hlcdc_plane_update(struct drm_plane *p,
				    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)
{
	return atmel_hlcdc_plane_update_with_mode(p, crtc, fb, crtc_x, crtc_y,
						  crtc_w, crtc_h, src_x, src_y,
						  src_w, src_h, &crtc->hwmode);
}

static int atmel_hlcdc_plane_disable(struct drm_plane *p)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);

	return atmel_hlcdc_layer_disable(&plane->layer);
}

static void atmel_hlcdc_plane_destroy(struct drm_plane *p)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);

	if (plane->base.fb)
		drm_framebuffer_unreference(plane->base.fb);

	atmel_hlcdc_layer_cleanup(p->dev, &plane->layer);

	drm_plane_cleanup(p);
	devm_kfree(p->dev->dev, plane);
}

static int atmel_hlcdc_plane_set_alpha(struct atmel_hlcdc_plane *plane,
				       u8 alpha)
{
	atmel_hlcdc_layer_update_start(&plane->layer);
	atmel_hlcdc_layer_update_cfg(&plane->layer,
				     plane->layer.desc->layout.general_config,
				     ATMEL_HLCDC_LAYER_GA_MASK,
				     alpha << ATMEL_HLCDC_LAYER_GA_SHIFT);
	atmel_hlcdc_layer_update_commit(&plane->layer);

	return 0;
}

static int atmel_hlcdc_plane_set_rotation(struct atmel_hlcdc_plane *plane,
					  unsigned int rotation)
{
	plane->rotation = rotation;

	return 0;
}

static int atmel_hlcdc_plane_set_property(struct drm_plane *p,
					  struct drm_property *property,
					  uint64_t value)
{
	struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
	struct atmel_hlcdc_plane_properties *props = plane->properties;

	if (property == props->alpha)
		atmel_hlcdc_plane_set_alpha(plane, value);
	else if (property == props->rotation)
		atmel_hlcdc_plane_set_rotation(plane, value);
	else
		return -EINVAL;

	return 0;
}

static void atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane,
				const struct atmel_hlcdc_layer_desc *desc,
				struct atmel_hlcdc_plane_properties *props)
{
	struct regmap *regmap = plane->layer.hlcdc->regmap;

	if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
	    desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
		drm_object_attach_property(&plane->base.base,
					   props->alpha, 255);

		/* Set default alpha value */
		regmap_update_bits(regmap,
				desc->regs_offset +
				ATMEL_HLCDC_LAYER_GENERAL_CFG(&plane->layer),
				ATMEL_HLCDC_LAYER_GA_MASK,
				ATMEL_HLCDC_LAYER_GA_MASK);
	}

	if (desc->layout.xstride && desc->layout.pstride)
		drm_object_attach_property(&plane->base.base,
					   props->rotation,
					   BIT(DRM_ROTATE_0));

	if (desc->layout.csc) {
		/*
		 * TODO: decare a "yuv-to-rgb-conv-factors" property to let
		 * userspace modify these factors (using a BLOB property ?).
		 */
		regmap_write(regmap,
			     desc->regs_offset +
			     ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 0),
			     0x4c900091);
		regmap_write(regmap,
			     desc->regs_offset +
			     ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 1),
			     0x7a5f5090);
		regmap_write(regmap,
			     desc->regs_offset +
			     ATMEL_HLCDC_LAYER_CSC_CFG(&plane->layer, 2),
			     0x40040890);
	}
}

static struct drm_plane_funcs layer_plane_funcs = {
	.update_plane = atmel_hlcdc_plane_update,
	.disable_plane = atmel_hlcdc_plane_disable,
	.set_property = atmel_hlcdc_plane_set_property,
	.destroy = atmel_hlcdc_plane_destroy,
};

static struct atmel_hlcdc_plane *
atmel_hlcdc_plane_create(struct drm_device *dev,
			 const struct atmel_hlcdc_layer_desc *desc,
			 struct atmel_hlcdc_plane_properties *props)
{
	struct atmel_hlcdc_plane *plane;
	enum drm_plane_type type;
	int ret;

	plane = devm_kzalloc(dev->dev, sizeof(*plane), GFP_KERNEL);
	if (!plane)
		return ERR_PTR(-ENOMEM);

	ret = atmel_hlcdc_layer_init(dev, &plane->layer, desc);
	if (ret)
		return ERR_PTR(ret);

	if (desc->type == ATMEL_HLCDC_BASE_LAYER)
		type = DRM_PLANE_TYPE_PRIMARY;
	else if (desc->type == ATMEL_HLCDC_CURSOR_LAYER)
		type = DRM_PLANE_TYPE_CURSOR;
	else
		type = DRM_PLANE_TYPE_OVERLAY;

	ret = drm_universal_plane_init(dev, &plane->base, 0,
				       &layer_plane_funcs,
				       desc->formats->formats,
				       desc->formats->nformats, type);
	if (ret)
		return ERR_PTR(ret);

	/* Set default property values*/
	atmel_hlcdc_plane_init_properties(plane, desc, props);

	return plane;
}

static struct atmel_hlcdc_plane_properties *
atmel_hlcdc_plane_create_properties(struct drm_device *dev)
{
	struct atmel_hlcdc_plane_properties *props;

	props = devm_kzalloc(dev->dev, sizeof(*props), GFP_KERNEL);
	if (!props)
		return ERR_PTR(-ENOMEM);

	props->alpha = drm_property_create_range(dev, 0, "alpha", 0, 255);
	if (!props->alpha)
		return ERR_PTR(-ENOMEM);

	props->rotation = drm_mode_create_rotation_property(dev,
						BIT(DRM_ROTATE_0) |
						BIT(DRM_ROTATE_90) |
						BIT(DRM_ROTATE_180) |
						BIT(DRM_ROTATE_270));
	if (!props->rotation)
		return ERR_PTR(-ENOMEM);

	return props;
}

struct atmel_hlcdc_planes *
atmel_hlcdc_create_planes(struct drm_device *dev)
{
	struct atmel_hlcdc_dc *dc = dev->dev_private;
	struct atmel_hlcdc_plane_properties *props;
	struct atmel_hlcdc_planes *planes;
	const struct atmel_hlcdc_layer_desc *descs = dc->desc->layers;
	int nlayers = dc->desc->nlayers;
	int i;

	planes = devm_kzalloc(dev->dev, sizeof(*planes), GFP_KERNEL);
	if (!planes)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < nlayers; i++) {
		if (descs[i].type == ATMEL_HLCDC_OVERLAY_LAYER)
			planes->noverlays++;
	}

	if (planes->noverlays) {
		planes->overlays = devm_kzalloc(dev->dev,
						planes->noverlays *
						sizeof(*planes->overlays),
						GFP_KERNEL);
		if (!planes->overlays)
			return ERR_PTR(-ENOMEM);
	}

	props = atmel_hlcdc_plane_create_properties(dev);
	if (IS_ERR(props))
		return ERR_CAST(props);

	planes->noverlays = 0;
	for (i = 0; i < nlayers; i++) {
		struct atmel_hlcdc_plane *plane;

		if (descs[i].type == ATMEL_HLCDC_PP_LAYER)
			continue;

		plane = atmel_hlcdc_plane_create(dev, &descs[i], props);
		if (IS_ERR(plane))
			return ERR_CAST(plane);

		plane->properties = props;

		switch (descs[i].type) {
		case ATMEL_HLCDC_BASE_LAYER:
			if (planes->primary)
				return ERR_PTR(-EINVAL);
			planes->primary = plane;
			break;

		case ATMEL_HLCDC_OVERLAY_LAYER:
			planes->overlays[planes->noverlays++] = plane;
			break;

		case ATMEL_HLCDC_CURSOR_LAYER:
			if (planes->cursor)
				return ERR_PTR(-EINVAL);
			planes->cursor = plane;
			break;

		default:
			break;
		}
	}

	return planes;
}
