/*
 * Copyright 2016 Linaro Ltd.
 * Copyright 2016 ZTE Corporation.
 *
 * 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.
 *
 */

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_fb_cma_helper.h>
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_plane_helper.h>
#include <drm/drmP.h>

#include "zx_common_regs.h"
#include "zx_drm_drv.h"
#include "zx_plane.h"
#include "zx_plane_regs.h"
#include "zx_vou.h"

static const uint32_t gl_formats[] = {
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_XRGB8888,
	DRM_FORMAT_RGB888,
	DRM_FORMAT_RGB565,
	DRM_FORMAT_ARGB1555,
	DRM_FORMAT_ARGB4444,
};

static const uint32_t vl_formats[] = {
	DRM_FORMAT_NV12,	/* Semi-planar YUV420 */
	DRM_FORMAT_YUV420,	/* Planar YUV420 */
	DRM_FORMAT_YUYV,	/* Packed YUV422 */
	DRM_FORMAT_YVYU,
	DRM_FORMAT_UYVY,
	DRM_FORMAT_VYUY,
	DRM_FORMAT_YUV444,	/* YUV444 8bit */
	/*
	 * TODO: add formats below that HW supports:
	 *  - YUV420 P010
	 *  - YUV420 Hantro
	 *  - YUV444 10bit
	 */
};

#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))

static int zx_vl_plane_atomic_check(struct drm_plane *plane,
				    struct drm_plane_state *plane_state)
{
	struct drm_framebuffer *fb = plane_state->fb;
	struct drm_crtc *crtc = plane_state->crtc;
	struct drm_crtc_state *crtc_state;
	int min_scale = FRAC_16_16(1, 8);
	int max_scale = FRAC_16_16(8, 1);

	if (!crtc || !fb)
		return 0;

	crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state,
							crtc);
	if (WARN_ON(!crtc_state))
		return -EINVAL;

	/* nothing to check when disabling or disabled */
	if (!crtc_state->enable)
		return 0;

	/* plane must be enabled */
	if (!plane_state->crtc)
		return -EINVAL;

	return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
						   min_scale, max_scale,
						   true, true);
}

static int zx_vl_get_fmt(uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_NV12:
		return VL_FMT_YUV420;
	case DRM_FORMAT_YUV420:
		return VL_YUV420_PLANAR | VL_FMT_YUV420;
	case DRM_FORMAT_YUYV:
		return VL_YUV422_YUYV | VL_FMT_YUV422;
	case DRM_FORMAT_YVYU:
		return VL_YUV422_YVYU | VL_FMT_YUV422;
	case DRM_FORMAT_UYVY:
		return VL_YUV422_UYVY | VL_FMT_YUV422;
	case DRM_FORMAT_VYUY:
		return VL_YUV422_VYUY | VL_FMT_YUV422;
	case DRM_FORMAT_YUV444:
		return VL_FMT_YUV444_8BIT;
	default:
		WARN_ONCE(1, "invalid pixel format %d\n", format);
		return -EINVAL;
	}
}

static inline void zx_vl_set_update(struct zx_plane *zplane)
{
	void __iomem *layer = zplane->layer;

	zx_writel_mask(layer + VL_CTRL0, VL_UPDATE, VL_UPDATE);
}

static inline void zx_vl_rsz_set_update(struct zx_plane *zplane)
{
	zx_writel(zplane->rsz + RSZ_VL_ENABLE_CFG, 1);
}

static int zx_vl_rsz_get_fmt(uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_NV12:
	case DRM_FORMAT_YUV420:
		return RSZ_VL_FMT_YCBCR420;
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_YVYU:
	case DRM_FORMAT_UYVY:
	case DRM_FORMAT_VYUY:
		return RSZ_VL_FMT_YCBCR422;
	case DRM_FORMAT_YUV444:
		return RSZ_VL_FMT_YCBCR444;
	default:
		WARN_ONCE(1, "invalid pixel format %d\n", format);
		return -EINVAL;
	}
}

static inline u32 rsz_step_value(u32 src, u32 dst)
{
	u32 val = 0;

	if (src == dst)
		val = 0;
	else if (src < dst)
		val = RSZ_PARA_STEP((src << 16) / dst);
	else if (src > dst)
		val = RSZ_DATA_STEP(src / dst) |
		      RSZ_PARA_STEP(((src << 16) / dst) & 0xffff);

	return val;
}

static void zx_vl_rsz_setup(struct zx_plane *zplane, uint32_t format,
			    u32 src_w, u32 src_h, u32 dst_w, u32 dst_h)
{
	void __iomem *rsz = zplane->rsz;
	u32 src_chroma_w = src_w;
	u32 src_chroma_h = src_h;
	int fmt;

	/* Set up source and destination resolution */
	zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1));
	zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1));

	/* Configure data format for VL RSZ */
	fmt = zx_vl_rsz_get_fmt(format);
	if (fmt >= 0)
		zx_writel_mask(rsz + RSZ_VL_CTRL_CFG, RSZ_VL_FMT_MASK, fmt);

	/* Calculate Chroma height and width */
	if (fmt == RSZ_VL_FMT_YCBCR420) {
		src_chroma_w = src_w >> 1;
		src_chroma_h = src_h >> 1;
	} else if (fmt == RSZ_VL_FMT_YCBCR422) {
		src_chroma_w = src_w >> 1;
	}

	/* Set up Luma and Chroma step registers */
	zx_writel(rsz + RSZ_VL_LUMA_HOR, rsz_step_value(src_w, dst_w));
	zx_writel(rsz + RSZ_VL_LUMA_VER, rsz_step_value(src_h, dst_h));
	zx_writel(rsz + RSZ_VL_CHROMA_HOR, rsz_step_value(src_chroma_w, dst_w));
	zx_writel(rsz + RSZ_VL_CHROMA_VER, rsz_step_value(src_chroma_h, dst_h));

	zx_vl_rsz_set_update(zplane);
}

static void zx_vl_plane_atomic_update(struct drm_plane *plane,
				      struct drm_plane_state *old_state)
{
	struct zx_plane *zplane = to_zx_plane(plane);
	struct drm_plane_state *state = plane->state;
	struct drm_framebuffer *fb = state->fb;
	struct drm_rect *src = &state->src;
	struct drm_rect *dst = &state->dst;
	struct drm_gem_cma_object *cma_obj;
	void __iomem *layer = zplane->layer;
	void __iomem *hbsc = zplane->hbsc;
	void __iomem *paddr_reg;
	dma_addr_t paddr;
	u32 src_x, src_y, src_w, src_h;
	u32 dst_x, dst_y, dst_w, dst_h;
	uint32_t format;
	int fmt;
	int num_planes;
	int i;

	if (!fb)
		return;

	format = fb->format->format;

	src_x = src->x1 >> 16;
	src_y = src->y1 >> 16;
	src_w = drm_rect_width(src) >> 16;
	src_h = drm_rect_height(src) >> 16;

	dst_x = dst->x1;
	dst_y = dst->y1;
	dst_w = drm_rect_width(dst);
	dst_h = drm_rect_height(dst);

	/* Set up data address registers for Y, Cb and Cr planes */
	num_planes = drm_format_num_planes(format);
	paddr_reg = layer + VL_Y;
	for (i = 0; i < num_planes; i++) {
		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
		paddr = cma_obj->paddr + fb->offsets[i];
		paddr += src_y * fb->pitches[i];
		paddr += src_x * drm_format_plane_cpp(format, i);
		zx_writel(paddr_reg, paddr);
		paddr_reg += 4;
	}

	/* Set up source height/width register */
	zx_writel(layer + VL_SRC_SIZE, GL_SRC_W(src_w) | GL_SRC_H(src_h));

	/* Set up start position register */
	zx_writel(layer + VL_POS_START, GL_POS_X(dst_x) | GL_POS_Y(dst_y));

	/* Set up end position register */
	zx_writel(layer + VL_POS_END,
		  GL_POS_X(dst_x + dst_w) | GL_POS_Y(dst_y + dst_h));

	/* Strides of Cb and Cr planes should be identical */
	zx_writel(layer + VL_STRIDE, LUMA_STRIDE(fb->pitches[0]) |
		  CHROMA_STRIDE(fb->pitches[1]));

	/* Set up video layer data format */
	fmt = zx_vl_get_fmt(format);
	if (fmt >= 0)
		zx_writel(layer + VL_CTRL1, fmt);

	/* Always use scaler since it exists (set for not bypass) */
	zx_writel_mask(layer + VL_CTRL2, VL_SCALER_BYPASS_MODE,
		       VL_SCALER_BYPASS_MODE);

	zx_vl_rsz_setup(zplane, format, src_w, src_h, dst_w, dst_h);

	/* Enable HBSC block */
	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN);

	zx_vou_layer_enable(plane);

	zx_vl_set_update(zplane);
}

static void zx_plane_atomic_disable(struct drm_plane *plane,
				    struct drm_plane_state *old_state)
{
	struct zx_plane *zplane = to_zx_plane(plane);
	void __iomem *hbsc = zplane->hbsc;

	zx_vou_layer_disable(plane);

	/* Disable HBSC block */
	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, 0);
}

static const struct drm_plane_helper_funcs zx_vl_plane_helper_funcs = {
	.atomic_check = zx_vl_plane_atomic_check,
	.atomic_update = zx_vl_plane_atomic_update,
	.atomic_disable = zx_plane_atomic_disable,
};

static int zx_gl_plane_atomic_check(struct drm_plane *plane,
				    struct drm_plane_state *plane_state)
{
	struct drm_framebuffer *fb = plane_state->fb;
	struct drm_crtc *crtc = plane_state->crtc;
	struct drm_crtc_state *crtc_state;

	if (!crtc || !fb)
		return 0;

	crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state,
							crtc);
	if (WARN_ON(!crtc_state))
		return -EINVAL;

	/* nothing to check when disabling or disabled */
	if (!crtc_state->enable)
		return 0;

	/* plane must be enabled */
	if (!plane_state->crtc)
		return -EINVAL;

	return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
						   DRM_PLANE_HELPER_NO_SCALING,
						   DRM_PLANE_HELPER_NO_SCALING,
						   false, true);
}

static int zx_gl_get_fmt(uint32_t format)
{
	switch (format) {
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_XRGB8888:
		return GL_FMT_ARGB8888;
	case DRM_FORMAT_RGB888:
		return GL_FMT_RGB888;
	case DRM_FORMAT_RGB565:
		return GL_FMT_RGB565;
	case DRM_FORMAT_ARGB1555:
		return GL_FMT_ARGB1555;
	case DRM_FORMAT_ARGB4444:
		return GL_FMT_ARGB4444;
	default:
		WARN_ONCE(1, "invalid pixel format %d\n", format);
		return -EINVAL;
	}
}

static inline void zx_gl_set_update(struct zx_plane *zplane)
{
	void __iomem *layer = zplane->layer;

	zx_writel_mask(layer + GL_CTRL0, GL_UPDATE, GL_UPDATE);
}

static inline void zx_gl_rsz_set_update(struct zx_plane *zplane)
{
	zx_writel(zplane->rsz + RSZ_ENABLE_CFG, 1);
}

static void zx_gl_rsz_setup(struct zx_plane *zplane, u32 src_w, u32 src_h,
			    u32 dst_w, u32 dst_h)
{
	void __iomem *rsz = zplane->rsz;

	zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1));
	zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1));

	zx_gl_rsz_set_update(zplane);
}

static void zx_gl_plane_atomic_update(struct drm_plane *plane,
				      struct drm_plane_state *old_state)
{
	struct zx_plane *zplane = to_zx_plane(plane);
	struct drm_framebuffer *fb = plane->state->fb;
	struct drm_gem_cma_object *cma_obj;
	void __iomem *layer = zplane->layer;
	void __iomem *csc = zplane->csc;
	void __iomem *hbsc = zplane->hbsc;
	u32 src_x, src_y, src_w, src_h;
	u32 dst_x, dst_y, dst_w, dst_h;
	unsigned int bpp;
	uint32_t format;
	dma_addr_t paddr;
	u32 stride;
	int fmt;

	if (!fb)
		return;

	format = fb->format->format;
	stride = fb->pitches[0];

	src_x = plane->state->src_x >> 16;
	src_y = plane->state->src_y >> 16;
	src_w = plane->state->src_w >> 16;
	src_h = plane->state->src_h >> 16;

	dst_x = plane->state->crtc_x;
	dst_y = plane->state->crtc_y;
	dst_w = plane->state->crtc_w;
	dst_h = plane->state->crtc_h;

	bpp = fb->format->cpp[0];

	cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
	paddr = cma_obj->paddr + fb->offsets[0];
	paddr += src_y * stride + src_x * bpp / 8;
	zx_writel(layer + GL_ADDR, paddr);

	/* Set up source height/width register */
	zx_writel(layer + GL_SRC_SIZE, GL_SRC_W(src_w) | GL_SRC_H(src_h));

	/* Set up start position register */
	zx_writel(layer + GL_POS_START, GL_POS_X(dst_x) | GL_POS_Y(dst_y));

	/* Set up end position register */
	zx_writel(layer + GL_POS_END,
		  GL_POS_X(dst_x + dst_w) | GL_POS_Y(dst_y + dst_h));

	/* Set up stride register */
	zx_writel(layer + GL_STRIDE, stride & 0xffff);

	/* Set up graphic layer data format */
	fmt = zx_gl_get_fmt(format);
	if (fmt >= 0)
		zx_writel_mask(layer + GL_CTRL1, GL_DATA_FMT_MASK,
			       fmt << GL_DATA_FMT_SHIFT);

	/* Initialize global alpha with a sane value */
	zx_writel_mask(layer + GL_CTRL2, GL_GLOBAL_ALPHA_MASK,
		       0xff << GL_GLOBAL_ALPHA_SHIFT);

	/* Setup CSC for the GL */
	if (dst_h > 720)
		zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
			       CSC_BT709_IMAGE_RGB2YCBCR << CSC_COV_MODE_SHIFT);
	else
		zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
			       CSC_BT601_IMAGE_RGB2YCBCR << CSC_COV_MODE_SHIFT);
	zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, CSC_WORK_ENABLE);

	/* Always use scaler since it exists (set for not bypass) */
	zx_writel_mask(layer + GL_CTRL3, GL_SCALER_BYPASS_MODE,
		       GL_SCALER_BYPASS_MODE);

	zx_gl_rsz_setup(zplane, src_w, src_h, dst_w, dst_h);

	/* Enable HBSC block */
	zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN);

	zx_vou_layer_enable(plane);

	zx_gl_set_update(zplane);
}

static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = {
	.atomic_check = zx_gl_plane_atomic_check,
	.atomic_update = zx_gl_plane_atomic_update,
	.atomic_disable = zx_plane_atomic_disable,
};

static void zx_plane_destroy(struct drm_plane *plane)
{
	drm_plane_helper_disable(plane, NULL);
	drm_plane_cleanup(plane);
}

static const struct drm_plane_funcs zx_plane_funcs = {
	.update_plane = drm_atomic_helper_update_plane,
	.disable_plane = drm_atomic_helper_disable_plane,
	.destroy = zx_plane_destroy,
	.reset = drm_atomic_helper_plane_reset,
	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
};

void zx_plane_set_update(struct drm_plane *plane)
{
	struct zx_plane *zplane = to_zx_plane(plane);

	/* Do nothing if the plane is not enabled */
	if (!plane->state->crtc)
		return;

	switch (plane->type) {
	case DRM_PLANE_TYPE_PRIMARY:
		zx_gl_rsz_set_update(zplane);
		zx_gl_set_update(zplane);
		break;
	case DRM_PLANE_TYPE_OVERLAY:
		zx_vl_rsz_set_update(zplane);
		zx_vl_set_update(zplane);
		break;
	default:
		WARN_ONCE(1, "unsupported plane type %d\n", plane->type);
	}
}

static void zx_plane_hbsc_init(struct zx_plane *zplane)
{
	void __iomem *hbsc = zplane->hbsc;

	/*
	 *  Initialize HBSC block with a sane configuration per recommedation
	 *  from ZTE BSP code.
	 */
	zx_writel(hbsc + HBSC_SATURATION, 0x200);
	zx_writel(hbsc + HBSC_HUE, 0x0);
	zx_writel(hbsc + HBSC_BRIGHT, 0x0);
	zx_writel(hbsc + HBSC_CONTRAST, 0x200);

	zx_writel(hbsc + HBSC_THRESHOLD_COL1, (0x3ac << 16) | 0x40);
	zx_writel(hbsc + HBSC_THRESHOLD_COL2, (0x3c0 << 16) | 0x40);
	zx_writel(hbsc + HBSC_THRESHOLD_COL3, (0x3c0 << 16) | 0x40);
}

int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane,
		  enum drm_plane_type type)
{
	const struct drm_plane_helper_funcs *helper;
	struct drm_plane *plane = &zplane->plane;
	struct device *dev = zplane->dev;
	const uint32_t *formats;
	unsigned int format_count;
	int ret;

	zx_plane_hbsc_init(zplane);

	switch (type) {
	case DRM_PLANE_TYPE_PRIMARY:
		helper = &zx_gl_plane_helper_funcs;
		formats = gl_formats;
		format_count = ARRAY_SIZE(gl_formats);
		break;
	case DRM_PLANE_TYPE_OVERLAY:
		helper = &zx_vl_plane_helper_funcs;
		formats = vl_formats;
		format_count = ARRAY_SIZE(vl_formats);
		break;
	default:
		return -ENODEV;
	}

	ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK,
				       &zx_plane_funcs, formats, format_count,
				       NULL, type, NULL);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret);
		return ret;
	}

	drm_plane_helper_add(plane, helper);

	return 0;
}
