// SPDX-License-Identifier: GPL-2.0+
/*
 * vsp1_brx.c  --  R-Car VSP1 Blend ROP Unit (BRU and BRS)
 *
 * Copyright (C) 2013 Renesas Corporation
 *
 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 */

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

#include <media/v4l2-subdev.h>

#include "vsp1.h"
#include "vsp1_brx.h"
#include "vsp1_dl.h"
#include "vsp1_pipe.h"
#include "vsp1_rwpf.h"
#include "vsp1_video.h"

#define BRX_MIN_SIZE				1U
#define BRX_MAX_SIZE				8190U

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

static inline void vsp1_brx_write(struct vsp1_brx *brx,
				  struct vsp1_dl_body *dlb, u32 reg, u32 data)
{
	vsp1_dl_body_write(dlb, brx->base + reg, data);
}

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

static int brx_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct vsp1_brx *brx =
		container_of(ctrl->handler, struct vsp1_brx, ctrls);

	switch (ctrl->id) {
	case V4L2_CID_BG_COLOR:
		brx->bgcolor = ctrl->val;
		break;
	}

	return 0;
}

static const struct v4l2_ctrl_ops brx_ctrl_ops = {
	.s_ctrl = brx_s_ctrl,
};

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

/*
 * The BRx can't perform format conversion, all sink and source formats must be
 * identical. We pick the format on the first sink pad (pad 0) and propagate it
 * to all other pads.
 */

static int brx_enum_mbus_code(struct v4l2_subdev *subdev,
			      struct v4l2_subdev_state *sd_state,
			      struct v4l2_subdev_mbus_code_enum *code)
{
	static const unsigned int codes[] = {
		MEDIA_BUS_FMT_ARGB8888_1X32,
		MEDIA_BUS_FMT_AYUV8_1X32,
	};

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

static int brx_enum_frame_size(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_state *sd_state,
			       struct v4l2_subdev_frame_size_enum *fse)
{
	if (fse->index)
		return -EINVAL;

	if (fse->code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
	    fse->code != MEDIA_BUS_FMT_AYUV8_1X32)
		return -EINVAL;

	fse->min_width = BRX_MIN_SIZE;
	fse->max_width = BRX_MAX_SIZE;
	fse->min_height = BRX_MIN_SIZE;
	fse->max_height = BRX_MAX_SIZE;

	return 0;
}

static struct v4l2_rect *brx_get_compose(struct vsp1_brx *brx,
					 struct v4l2_subdev_state *sd_state,
					 unsigned int pad)
{
	return v4l2_subdev_state_get_compose(sd_state, pad);
}

static void brx_try_format(struct vsp1_brx *brx,
			   struct v4l2_subdev_state *sd_state,
			   unsigned int pad, struct v4l2_mbus_framefmt *fmt)
{
	struct v4l2_mbus_framefmt *format;

	switch (pad) {
	case BRX_PAD_SINK(0):
		/* Default to YUV if the requested format is not supported. */
		if (fmt->code != MEDIA_BUS_FMT_ARGB8888_1X32 &&
		    fmt->code != MEDIA_BUS_FMT_AYUV8_1X32)
			fmt->code = MEDIA_BUS_FMT_AYUV8_1X32;
		break;

	default:
		/* The BRx can't perform format conversion. */
		format = vsp1_entity_get_pad_format(&brx->entity, sd_state,
						    BRX_PAD_SINK(0));
		fmt->code = format->code;
		break;
	}

	fmt->width = clamp(fmt->width, BRX_MIN_SIZE, BRX_MAX_SIZE);
	fmt->height = clamp(fmt->height, BRX_MIN_SIZE, BRX_MAX_SIZE);
	fmt->field = V4L2_FIELD_NONE;
	fmt->colorspace = V4L2_COLORSPACE_SRGB;
}

static int brx_set_format(struct v4l2_subdev *subdev,
			  struct v4l2_subdev_state *sd_state,
			  struct v4l2_subdev_format *fmt)
{
	struct vsp1_brx *brx = to_brx(subdev);
	struct v4l2_subdev_state *state;
	struct v4l2_mbus_framefmt *format;
	int ret = 0;

	mutex_lock(&brx->entity.lock);

	state = vsp1_entity_get_state(&brx->entity, sd_state, fmt->which);
	if (!state) {
		ret = -EINVAL;
		goto done;
	}

	brx_try_format(brx, state, fmt->pad, &fmt->format);

	format = vsp1_entity_get_pad_format(&brx->entity, state, fmt->pad);
	*format = fmt->format;

	/* Reset the compose rectangle. */
	if (fmt->pad != brx->entity.source_pad) {
		struct v4l2_rect *compose;

		compose = brx_get_compose(brx, state, fmt->pad);
		compose->left = 0;
		compose->top = 0;
		compose->width = format->width;
		compose->height = format->height;
	}

	/* Propagate the format code to all pads. */
	if (fmt->pad == BRX_PAD_SINK(0)) {
		unsigned int i;

		for (i = 0; i <= brx->entity.source_pad; ++i) {
			format = vsp1_entity_get_pad_format(&brx->entity,
							    state, i);
			format->code = fmt->format.code;
		}
	}

done:
	mutex_unlock(&brx->entity.lock);
	return ret;
}

static int brx_get_selection(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_state *sd_state,
			     struct v4l2_subdev_selection *sel)
{
	struct vsp1_brx *brx = to_brx(subdev);
	struct v4l2_subdev_state *state;

	if (sel->pad == brx->entity.source_pad)
		return -EINVAL;

	switch (sel->target) {
	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
		sel->r.left = 0;
		sel->r.top = 0;
		sel->r.width = BRX_MAX_SIZE;
		sel->r.height = BRX_MAX_SIZE;
		return 0;

	case V4L2_SEL_TGT_COMPOSE:
		state = vsp1_entity_get_state(&brx->entity, sd_state,
					      sel->which);
		if (!state)
			return -EINVAL;

		mutex_lock(&brx->entity.lock);
		sel->r = *brx_get_compose(brx, state, sel->pad);
		mutex_unlock(&brx->entity.lock);
		return 0;

	default:
		return -EINVAL;
	}
}

static int brx_set_selection(struct v4l2_subdev *subdev,
			     struct v4l2_subdev_state *sd_state,
			     struct v4l2_subdev_selection *sel)
{
	struct vsp1_brx *brx = to_brx(subdev);
	struct v4l2_subdev_state *state;
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *compose;
	int ret = 0;

	if (sel->pad == brx->entity.source_pad)
		return -EINVAL;

	if (sel->target != V4L2_SEL_TGT_COMPOSE)
		return -EINVAL;

	mutex_lock(&brx->entity.lock);

	state = vsp1_entity_get_state(&brx->entity, sd_state, sel->which);
	if (!state) {
		ret = -EINVAL;
		goto done;
	}

	/*
	 * The compose rectangle top left corner must be inside the output
	 * frame.
	 */
	format = vsp1_entity_get_pad_format(&brx->entity, state,
					    brx->entity.source_pad);
	sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
	sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);

	/*
	 * Scaling isn't supported, the compose rectangle size must be identical
	 * to the sink format size.
	 */
	format = vsp1_entity_get_pad_format(&brx->entity, state, sel->pad);
	sel->r.width = format->width;
	sel->r.height = format->height;

	compose = brx_get_compose(brx, state, sel->pad);
	*compose = sel->r;

done:
	mutex_unlock(&brx->entity.lock);
	return ret;
}

static const struct v4l2_subdev_pad_ops brx_pad_ops = {
	.enum_mbus_code = brx_enum_mbus_code,
	.enum_frame_size = brx_enum_frame_size,
	.get_fmt = vsp1_subdev_get_pad_format,
	.set_fmt = brx_set_format,
	.get_selection = brx_get_selection,
	.set_selection = brx_set_selection,
};

static const struct v4l2_subdev_ops brx_ops = {
	.pad    = &brx_pad_ops,
};

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

static void brx_configure_stream(struct vsp1_entity *entity,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_list *dl,
				 struct vsp1_dl_body *dlb)
{
	struct vsp1_brx *brx = to_brx(&entity->subdev);
	struct v4l2_mbus_framefmt *format;
	unsigned int flags;
	unsigned int i;

	format = vsp1_entity_get_pad_format(&brx->entity, brx->entity.state,
					    brx->entity.source_pad);

	/*
	 * The hardware is extremely flexible but we have no userspace API to
	 * expose all the parameters, nor is it clear whether we would have use
	 * cases for all the supported modes. Let's just hardcode the parameters
	 * to sane default values for now.
	 */

	/*
	 * Disable dithering and enable color data normalization unless the
	 * format at the pipeline output is premultiplied.
	 */
	flags = pipe->output ? pipe->output->format.flags : 0;
	vsp1_brx_write(brx, dlb, VI6_BRU_INCTRL,
		       flags & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA ?
		       0 : VI6_BRU_INCTRL_NRM);

	/*
	 * Set the background position to cover the whole output image and
	 * configure its color.
	 */
	vsp1_brx_write(brx, dlb, VI6_BRU_VIRRPF_SIZE,
		       (format->width << VI6_BRU_VIRRPF_SIZE_HSIZE_SHIFT) |
		       (format->height << VI6_BRU_VIRRPF_SIZE_VSIZE_SHIFT));
	vsp1_brx_write(brx, dlb, VI6_BRU_VIRRPF_LOC, 0);

	vsp1_brx_write(brx, dlb, VI6_BRU_VIRRPF_COL, brx->bgcolor |
		       (0xff << VI6_BRU_VIRRPF_COL_A_SHIFT));

	/*
	 * Route BRU input 1 as SRC input to the ROP unit and configure the ROP
	 * unit with a NOP operation to make BRU input 1 available as the
	 * Blend/ROP unit B SRC input. Only needed for BRU, the BRS has no ROP
	 * unit.
	 */
	if (entity->type == VSP1_ENTITY_BRU)
		vsp1_brx_write(brx, dlb, VI6_BRU_ROP,
			       VI6_BRU_ROP_DSTSEL_BRUIN(1) |
			       VI6_BRU_ROP_CROP(VI6_ROP_NOP) |
			       VI6_BRU_ROP_AROP(VI6_ROP_NOP));

	for (i = 0; i < brx->entity.source_pad; ++i) {
		bool premultiplied = false;
		u32 ctrl = 0;

		/*
		 * Configure all Blend/ROP units corresponding to an enabled BRx
		 * input for alpha blending. Blend/ROP units corresponding to
		 * disabled BRx inputs are used in ROP NOP mode to ignore the
		 * SRC input.
		 */
		if (brx->inputs[i].rpf) {
			ctrl |= VI6_BRU_CTRL_RBC;

			premultiplied = brx->inputs[i].rpf->format.flags
				      & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;
		} else {
			ctrl |= VI6_BRU_CTRL_CROP(VI6_ROP_NOP)
			     |  VI6_BRU_CTRL_AROP(VI6_ROP_NOP);
		}

		/*
		 * Select the virtual RPF as the Blend/ROP unit A DST input to
		 * serve as a background color.
		 */
		if (i == 0)
			ctrl |= VI6_BRU_CTRL_DSTSEL_VRPF;

		/*
		 * Route inputs 0 to 3 as SRC inputs to Blend/ROP units A to D
		 * in that order. In the BRU the Blend/ROP unit B SRC is
		 * hardwired to the ROP unit output, the corresponding register
		 * bits must be set to 0. The BRS has no ROP unit and doesn't
		 * need any special processing.
		 */
		if (!(entity->type == VSP1_ENTITY_BRU && i == 1))
			ctrl |= VI6_BRU_CTRL_SRCSEL_BRUIN(i);

		vsp1_brx_write(brx, dlb, VI6_BRU_CTRL(i), ctrl);

		/*
		 * Hardcode the blending formula to
		 *
		 *	DSTc = DSTc * (1 - SRCa) + SRCc * SRCa
		 *	DSTa = DSTa * (1 - SRCa) + SRCa
		 *
		 * when the SRC input isn't premultiplied, and to
		 *
		 *	DSTc = DSTc * (1 - SRCa) + SRCc
		 *	DSTa = DSTa * (1 - SRCa) + SRCa
		 *
		 * otherwise.
		 */
		vsp1_brx_write(brx, dlb, VI6_BRU_BLD(i),
			       VI6_BRU_BLD_CCMDX_255_SRC_A |
			       (premultiplied ? VI6_BRU_BLD_CCMDY_COEFY :
						VI6_BRU_BLD_CCMDY_SRC_A) |
			       VI6_BRU_BLD_ACMDX_255_SRC_A |
			       VI6_BRU_BLD_ACMDY_COEFY |
			       (0xff << VI6_BRU_BLD_COEFY_SHIFT));
	}
}

static const struct vsp1_entity_operations brx_entity_ops = {
	.configure_stream = brx_configure_stream,
};

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

struct vsp1_brx *vsp1_brx_create(struct vsp1_device *vsp1,
				 enum vsp1_entity_type type)
{
	struct vsp1_brx *brx;
	unsigned int num_pads;
	const char *name;
	int ret;

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

	brx->base = type == VSP1_ENTITY_BRU ? VI6_BRU_BASE : VI6_BRS_BASE;
	brx->entity.ops = &brx_entity_ops;
	brx->entity.type = type;

	if (type == VSP1_ENTITY_BRU) {
		num_pads = vsp1->info->num_bru_inputs + 1;
		name = "bru";
	} else {
		num_pads = 3;
		name = "brs";
	}

	ret = vsp1_entity_init(vsp1, &brx->entity, name, num_pads, &brx_ops,
			       MEDIA_ENT_F_PROC_VIDEO_COMPOSER);
	if (ret < 0)
		return ERR_PTR(ret);

	/* Initialize the control handler. */
	v4l2_ctrl_handler_init(&brx->ctrls, 1);
	v4l2_ctrl_new_std(&brx->ctrls, &brx_ctrl_ops, V4L2_CID_BG_COLOR,
			  0, 0xffffff, 1, 0);

	brx->bgcolor = 0;

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

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

	return brx;
}
