/*
 * vsp1_clu.c  --  R-Car VSP1 Cubic Look-Up Table
 *
 * Copyright (C) 2015-2016 Renesas Electronics Corporation
 *
 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/device.h>
#include <linux/slab.h>

#include <media/v4l2-subdev.h>

#include "vsp1.h"
#include "vsp1_clu.h"
#include "vsp1_dl.h"

#define CLU_MIN_SIZE				4U
#define CLU_MAX_SIZE				8190U

/* -----------------------------------------------------------------------------
 * Device Access
 */

static inline void vsp1_clu_write(struct vsp1_clu *clu, struct vsp1_dl_list *dl,
				  u32 reg, u32 data)
{
	vsp1_dl_list_write(dl, reg, data);
}

/* -----------------------------------------------------------------------------
 * Controls
 */

#define V4L2_CID_VSP1_CLU_TABLE			(V4L2_CID_USER_BASE | 0x1001)
#define V4L2_CID_VSP1_CLU_MODE			(V4L2_CID_USER_BASE | 0x1002)
#define V4L2_CID_VSP1_CLU_MODE_2D		0
#define V4L2_CID_VSP1_CLU_MODE_3D		1

static int clu_set_table(struct vsp1_clu *clu, struct v4l2_ctrl *ctrl)
{
	struct vsp1_dl_body *dlb;
	unsigned int i;

	dlb = vsp1_dl_fragment_alloc(clu->entity.vsp1, 1 + 17 * 17 * 17);
	if (!dlb)
		return -ENOMEM;

	vsp1_dl_fragment_write(dlb, VI6_CLU_ADDR, 0);
	for (i = 0; i < 17 * 17 * 17; ++i)
		vsp1_dl_fragment_write(dlb, VI6_CLU_DATA, ctrl->p_new.p_u32[i]);

	spin_lock_irq(&clu->lock);
	swap(clu->clu, dlb);
	spin_unlock_irq(&clu->lock);

	vsp1_dl_fragment_free(dlb);
	return 0;
}

static int clu_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct vsp1_clu *clu =
		container_of(ctrl->handler, struct vsp1_clu, ctrls);

	switch (ctrl->id) {
	case V4L2_CID_VSP1_CLU_TABLE:
		clu_set_table(clu, ctrl);
		break;

	case V4L2_CID_VSP1_CLU_MODE:
		clu->mode = ctrl->val;
		break;
	}

	return 0;
}

static const struct v4l2_ctrl_ops clu_ctrl_ops = {
	.s_ctrl = clu_s_ctrl,
};

static const struct v4l2_ctrl_config clu_table_control = {
	.ops = &clu_ctrl_ops,
	.id = V4L2_CID_VSP1_CLU_TABLE,
	.name = "Look-Up Table",
	.type = V4L2_CTRL_TYPE_U32,
	.min = 0x00000000,
	.max = 0x00ffffff,
	.step = 1,
	.def = 0,
	.dims = { 17, 17, 17 },
};

static const char * const clu_mode_menu[] = {
	"2D",
	"3D",
	NULL,
};

static const struct v4l2_ctrl_config clu_mode_control = {
	.ops = &clu_ctrl_ops,
	.id = V4L2_CID_VSP1_CLU_MODE,
	.name = "Mode",
	.type = V4L2_CTRL_TYPE_MENU,
	.min = 0,
	.max = 1,
	.def = 1,
	.qmenu = clu_mode_menu,
};

/* -----------------------------------------------------------------------------
 * V4L2 Subdevice Pad Operations
 */

static int clu_enum_mbus_code(struct v4l2_subdev *subdev,
			      struct v4l2_subdev_pad_config *cfg,
			      struct v4l2_subdev_mbus_code_enum *code)
{
	static const unsigned int codes[] = {
		MEDIA_BUS_FMT_ARGB8888_1X32,
		MEDIA_BUS_FMT_AHSV8888_1X32,
		MEDIA_BUS_FMT_AYUV8_1X32,
	};

	return vsp1_subdev_enum_mbus_code(subdev, cfg, code, codes,
					  ARRAY_SIZE(codes));
}

static int clu_enum_frame_size(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_frame_size_enum *fse)
{
	return vsp1_subdev_enum_frame_size(subdev, cfg, fse, CLU_MIN_SIZE,
					   CLU_MIN_SIZE, CLU_MAX_SIZE,
					   CLU_MAX_SIZE);
}

static int clu_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_pad_config *cfg,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_clu *clu = to_clu(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;

	config = vsp1_entity_get_pad_config(&clu->entity, cfg, fmt->which);
	if (!config)
		return -EINVAL;

	/* Default to YUV if the requested format is not supported. */
	if (fmt->format.code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AHSV8888_1X32 &&
	    fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
		fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;

	format = vsp1_entity_get_pad_format(&clu->entity, config, fmt->pad);

	if (fmt->pad == CLU_PAD_SOURCE) {
		/* The CLU output format can't be modified. */
		fmt->format = *format;
		return 0;
	}

	format->code = fmt->format.code;
	format->width = clamp_t(unsigned int, fmt->format.width,
				CLU_MIN_SIZE, CLU_MAX_SIZE);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 CLU_MIN_SIZE, CLU_MAX_SIZE);
	format->field = V4L2_FIELD_NONE;
	format->colorspace = V4L2_COLORSPACE_SRGB;

	fmt->format = *format;

	/* Propagate the format to the source pad. */
	format = vsp1_entity_get_pad_format(&clu->entity, config,
					    CLU_PAD_SOURCE);
	*format = fmt->format;

	return 0;
}

/* -----------------------------------------------------------------------------
 * V4L2 Subdevice Operations
 */

static const struct v4l2_subdev_pad_ops clu_pad_ops = {
	.init_cfg = vsp1_entity_init_cfg,
	.enum_mbus_code = clu_enum_mbus_code,
	.enum_frame_size = clu_enum_frame_size,
	.get_fmt = vsp1_subdev_get_pad_format,
	.set_fmt = clu_set_format,
};

static const struct v4l2_subdev_ops clu_ops = {
	.pad    = &clu_pad_ops,
};

/* -----------------------------------------------------------------------------
 * VSP1 Entity Operations
 */

static void clu_configure(struct vsp1_entity *entity,
			  struct vsp1_pipeline *pipe,
			  struct vsp1_dl_list *dl, bool full)
{
	struct vsp1_clu *clu = to_clu(&entity->subdev);
	struct vsp1_dl_body *dlb;
	unsigned long flags;
	u32 ctrl = VI6_CLU_CTRL_AAI | VI6_CLU_CTRL_MVS | VI6_CLU_CTRL_EN;

	/* The format can't be changed during streaming, only verify it at
	 * stream start and store the information internally for future partial
	 * reconfiguration calls.
	 */
	if (full) {
		struct v4l2_mbus_framefmt *format;

		format = vsp1_entity_get_pad_format(&clu->entity,
						    clu->entity.config,
						    CLU_PAD_SINK);
		clu->yuv_mode = format->code == MEDIA_BUS_FMT_AYUV8_1X32;
		return;
	}

	/* 2D mode can only be used with the YCbCr pixel encoding. */
	if (clu->mode == V4L2_CID_VSP1_CLU_MODE_2D && clu->yuv_mode)
		ctrl |= VI6_CLU_CTRL_AX1I_2D | VI6_CLU_CTRL_AX2I_2D
		     |  VI6_CLU_CTRL_OS0_2D | VI6_CLU_CTRL_OS1_2D
		     |  VI6_CLU_CTRL_OS2_2D | VI6_CLU_CTRL_M2D;

	vsp1_clu_write(clu, dl, VI6_CLU_CTRL, ctrl);

	spin_lock_irqsave(&clu->lock, flags);
	dlb = clu->clu;
	clu->clu = NULL;
	spin_unlock_irqrestore(&clu->lock, flags);

	if (dlb)
		vsp1_dl_list_add_fragment(dl, dlb);
}

static const struct vsp1_entity_operations clu_entity_ops = {
	.configure = clu_configure,
};

/* -----------------------------------------------------------------------------
 * Initialization and Cleanup
 */

struct vsp1_clu *vsp1_clu_create(struct vsp1_device *vsp1)
{
	struct vsp1_clu *clu;
	int ret;

	clu = devm_kzalloc(vsp1->dev, sizeof(*clu), GFP_KERNEL);
	if (clu == NULL)
		return ERR_PTR(-ENOMEM);

	spin_lock_init(&clu->lock);

	clu->entity.ops = &clu_entity_ops;
	clu->entity.type = VSP1_ENTITY_CLU;

	ret = vsp1_entity_init(vsp1, &clu->entity, "clu", 2, &clu_ops,
			       MEDIA_ENT_F_PROC_VIDEO_LUT);
	if (ret < 0)
		return ERR_PTR(ret);

	/* Initialize the control handler. */
	v4l2_ctrl_handler_init(&clu->ctrls, 2);
	v4l2_ctrl_new_custom(&clu->ctrls, &clu_table_control, NULL);
	v4l2_ctrl_new_custom(&clu->ctrls, &clu_mode_control, NULL);

	clu->entity.subdev.ctrl_handler = &clu->ctrls;

	if (clu->ctrls.error) {
		dev_err(vsp1->dev, "clu: failed to initialize controls\n");
		ret = clu->ctrls.error;
		vsp1_entity_destroy(&clu->entity);
		return ERR_PTR(ret);
	}

	v4l2_ctrl_handler_setup(&clu->ctrls);

	return clu;
}
