// SPDX-License-Identifier: GPL-2.0+
/*
 * vsp1_rpf.c  --  R-Car VSP1 Read Pixel Formatter
 *
 * Copyright (C) 2013-2014 Renesas Electronics Corporation
 *
 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 */

#include <linux/device.h>

#include <media/v4l2-subdev.h>

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

#define RPF_MAX_WIDTH				8190
#define RPF_MAX_HEIGHT				8190

/* Pre extended display list command data structure. */
struct vsp1_extcmd_auto_fld_body {
	u32 top_y0;
	u32 bottom_y0;
	u32 top_c0;
	u32 bottom_c0;
	u32 top_c1;
	u32 bottom_c1;
	u32 reserved0;
	u32 reserved1;
} __packed;

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

static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf,
				  struct vsp1_dl_body *dlb, u32 reg, u32 data)
{
	vsp1_dl_body_write(dlb, reg + rpf->entity.index * VI6_RPF_OFFSET,
			       data);
}

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

static const struct v4l2_subdev_ops rpf_ops = {
	.pad    = &vsp1_rwpf_pad_ops,
};

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

static void rpf_configure_stream(struct vsp1_entity *entity,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_body *dlb)
{
	struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
	const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
	const struct v4l2_pix_format_mplane *format = &rpf->format;
	const struct v4l2_mbus_framefmt *source_format;
	const struct v4l2_mbus_framefmt *sink_format;
	unsigned int left = 0;
	unsigned int top = 0;
	u32 pstride;
	u32 infmt;

	/* Stride */
	pstride = format->plane_fmt[0].bytesperline
		<< VI6_RPF_SRCM_PSTRIDE_Y_SHIFT;
	if (format->num_planes > 1)
		pstride |= format->plane_fmt[1].bytesperline
			<< VI6_RPF_SRCM_PSTRIDE_C_SHIFT;

	/*
	 * pstride has both STRIDE_Y and STRIDE_C, but multiplying the whole
	 * of pstride by 2 is conveniently OK here as we are multiplying both
	 * values.
	 */
	if (pipe->interlaced)
		pstride *= 2;

	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_PSTRIDE, pstride);

	/* Format */
	sink_format = vsp1_entity_get_pad_format(&rpf->entity,
						 rpf->entity.config,
						 RWPF_PAD_SINK);
	source_format = vsp1_entity_get_pad_format(&rpf->entity,
						   rpf->entity.config,
						   RWPF_PAD_SOURCE);

	infmt = VI6_RPF_INFMT_CIPM
	      | (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT);

	if (fmtinfo->swap_yc)
		infmt |= VI6_RPF_INFMT_SPYCS;
	if (fmtinfo->swap_uv)
		infmt |= VI6_RPF_INFMT_SPUVS;

	if (sink_format->code != source_format->code)
		infmt |= VI6_RPF_INFMT_CSC;

	vsp1_rpf_write(rpf, dlb, VI6_RPF_INFMT, infmt);
	vsp1_rpf_write(rpf, dlb, VI6_RPF_DSWAP, fmtinfo->swap);

	/* Output location */
	if (pipe->brx) {
		const struct v4l2_rect *compose;

		compose = vsp1_entity_get_pad_selection(pipe->brx,
							pipe->brx->config,
							rpf->brx_input,
							V4L2_SEL_TGT_COMPOSE);
		left = compose->left;
		top = compose->top;
	}

	if (pipe->interlaced)
		top /= 2;

	vsp1_rpf_write(rpf, dlb, VI6_RPF_LOC,
		       (left << VI6_RPF_LOC_HCOORD_SHIFT) |
		       (top << VI6_RPF_LOC_VCOORD_SHIFT));

	/*
	 * On Gen2 use the alpha channel (extended to 8 bits) when available or
	 * a fixed alpha value set through the V4L2_CID_ALPHA_COMPONENT control
	 * otherwise.
	 *
	 * The Gen3 RPF has extended alpha capability and can both multiply the
	 * alpha channel by a fixed global alpha value, and multiply the pixel
	 * components to convert the input to premultiplied alpha.
	 *
	 * As alpha premultiplication is available in the BRx for both Gen2 and
	 * Gen3 we handle it there and use the Gen3 alpha multiplier for global
	 * alpha multiplication only. This however prevents conversion to
	 * premultiplied alpha if no BRx is present in the pipeline. If that use
	 * case turns out to be useful we will revisit the implementation (for
	 * Gen3 only).
	 *
	 * We enable alpha multiplication on Gen3 using the fixed alpha value
	 * set through the V4L2_CID_ALPHA_COMPONENT control when the input
	 * contains an alpha channel. On Gen2 the global alpha is ignored in
	 * that case.
	 *
	 * In all cases, disable color keying.
	 */
	vsp1_rpf_write(rpf, dlb, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_AEXT_EXT |
		       (fmtinfo->alpha ? VI6_RPF_ALPH_SEL_ASEL_PACKED
				       : VI6_RPF_ALPH_SEL_ASEL_FIXED));

	if (entity->vsp1->info->gen == 3) {
		u32 mult;

		if (fmtinfo->alpha) {
			/*
			 * When the input contains an alpha channel enable the
			 * alpha multiplier. If the input is premultiplied we
			 * need to multiply both the alpha channel and the pixel
			 * components by the global alpha value to keep them
			 * premultiplied. Otherwise multiply the alpha channel
			 * only.
			 */
			bool premultiplied = format->flags
					   & V4L2_PIX_FMT_FLAG_PREMUL_ALPHA;

			mult = VI6_RPF_MULT_ALPHA_A_MMD_RATIO
			     | (premultiplied ?
				VI6_RPF_MULT_ALPHA_P_MMD_RATIO :
				VI6_RPF_MULT_ALPHA_P_MMD_NONE);
		} else {
			/*
			 * When the input doesn't contain an alpha channel the
			 * global alpha value is applied in the unpacking unit,
			 * the alpha multiplier isn't needed and must be
			 * disabled.
			 */
			mult = VI6_RPF_MULT_ALPHA_A_MMD_NONE
			     | VI6_RPF_MULT_ALPHA_P_MMD_NONE;
		}

		rpf->mult_alpha = mult;
	}

	vsp1_rpf_write(rpf, dlb, VI6_RPF_MSK_CTRL, 0);
	vsp1_rpf_write(rpf, dlb, VI6_RPF_CKEY_CTRL, 0);

}

static void vsp1_rpf_configure_autofld(struct vsp1_rwpf *rpf,
				       struct vsp1_dl_list *dl)
{
	const struct v4l2_pix_format_mplane *format = &rpf->format;
	struct vsp1_dl_ext_cmd *cmd;
	struct vsp1_extcmd_auto_fld_body *auto_fld;
	u32 offset_y, offset_c;

	cmd = vsp1_dl_get_pre_cmd(dl);
	if (WARN_ONCE(!cmd, "Failed to obtain an autofld cmd"))
		return;

	/* Re-index our auto_fld to match the current RPF. */
	auto_fld = cmd->data;
	auto_fld = &auto_fld[rpf->entity.index];

	auto_fld->top_y0 = rpf->mem.addr[0];
	auto_fld->top_c0 = rpf->mem.addr[1];
	auto_fld->top_c1 = rpf->mem.addr[2];

	offset_y = format->plane_fmt[0].bytesperline;
	offset_c = format->plane_fmt[1].bytesperline;

	auto_fld->bottom_y0 = rpf->mem.addr[0] + offset_y;
	auto_fld->bottom_c0 = rpf->mem.addr[1] + offset_c;
	auto_fld->bottom_c1 = rpf->mem.addr[2] + offset_c;

	cmd->flags |= VI6_DL_EXT_AUTOFLD_INT | BIT(16 + rpf->entity.index);
}

static void rpf_configure_frame(struct vsp1_entity *entity,
				struct vsp1_pipeline *pipe,
				struct vsp1_dl_list *dl,
				struct vsp1_dl_body *dlb)
{
	struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);

	vsp1_rpf_write(rpf, dlb, VI6_RPF_VRTCOL_SET,
		       rpf->alpha << VI6_RPF_VRTCOL_SET_LAYA_SHIFT);
	vsp1_rpf_write(rpf, dlb, VI6_RPF_MULT_ALPHA, rpf->mult_alpha |
		       (rpf->alpha << VI6_RPF_MULT_ALPHA_RATIO_SHIFT));

	vsp1_pipeline_propagate_alpha(pipe, dlb, rpf->alpha);
}

static void rpf_configure_partition(struct vsp1_entity *entity,
				    struct vsp1_pipeline *pipe,
				    struct vsp1_dl_list *dl,
				    struct vsp1_dl_body *dlb)
{
	struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
	struct vsp1_rwpf_memory mem = rpf->mem;
	struct vsp1_device *vsp1 = rpf->entity.vsp1;
	const struct vsp1_format_info *fmtinfo = rpf->fmtinfo;
	const struct v4l2_pix_format_mplane *format = &rpf->format;
	struct v4l2_rect crop;

	/*
	 * Source size and crop offsets.
	 *
	 * The crop offsets correspond to the location of the crop
	 * rectangle top left corner in the plane buffer. Only two
	 * offsets are needed, as planes 2 and 3 always have identical
	 * strides.
	 */
	crop = *vsp1_rwpf_get_crop(rpf, rpf->entity.config);

	/*
	 * Partition Algorithm Control
	 *
	 * The partition algorithm can split this frame into multiple
	 * slices. We must scale our partition window based on the pipe
	 * configuration to match the destination partition window.
	 * To achieve this, we adjust our crop to provide a 'sub-crop'
	 * matching the expected partition window. Only 'left' and
	 * 'width' need to be adjusted.
	 */
	if (pipe->partitions > 1) {
		crop.width = pipe->partition->rpf.width;
		crop.left += pipe->partition->rpf.left;
	}

	if (pipe->interlaced) {
		crop.height = round_down(crop.height / 2, fmtinfo->vsub);
		crop.top = round_down(crop.top / 2, fmtinfo->vsub);
	}

	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRC_BSIZE,
		       (crop.width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) |
		       (crop.height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT));
	vsp1_rpf_write(rpf, dlb, VI6_RPF_SRC_ESIZE,
		       (crop.width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) |
		       (crop.height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT));

	mem.addr[0] += crop.top * format->plane_fmt[0].bytesperline
		     + crop.left * fmtinfo->bpp[0] / 8;

	if (format->num_planes > 1) {
		unsigned int offset;

		offset = crop.top * format->plane_fmt[1].bytesperline
		       + crop.left / fmtinfo->hsub
		       * fmtinfo->bpp[1] / 8;
		mem.addr[1] += offset;
		mem.addr[2] += offset;
	}

	/*
	 * On Gen3 hardware the SPUVS bit has no effect on 3-planar
	 * formats. Swap the U and V planes manually in that case.
	 */
	if (vsp1->info->gen == 3 && format->num_planes == 3 &&
	    fmtinfo->swap_uv)
		swap(mem.addr[1], mem.addr[2]);

	/*
	 * Interlaced pipelines will use the extended pre-cmd to process
	 * SRCM_ADDR_{Y,C0,C1}
	 */
	if (pipe->interlaced) {
		vsp1_rpf_configure_autofld(rpf, dl);
	} else {
		vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_Y, mem.addr[0]);
		vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_C0, mem.addr[1]);
		vsp1_rpf_write(rpf, dlb, VI6_RPF_SRCM_ADDR_C1, mem.addr[2]);
	}
}

static void rpf_partition(struct vsp1_entity *entity,
			  struct vsp1_pipeline *pipe,
			  struct vsp1_partition *partition,
			  unsigned int partition_idx,
			  struct vsp1_partition_window *window)
{
	partition->rpf = *window;
}

static const struct vsp1_entity_operations rpf_entity_ops = {
	.configure_stream = rpf_configure_stream,
	.configure_frame = rpf_configure_frame,
	.configure_partition = rpf_configure_partition,
	.partition = rpf_partition,
};

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

struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index)
{
	struct vsp1_rwpf *rpf;
	char name[6];
	int ret;

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

	rpf->max_width = RPF_MAX_WIDTH;
	rpf->max_height = RPF_MAX_HEIGHT;

	rpf->entity.ops = &rpf_entity_ops;
	rpf->entity.type = VSP1_ENTITY_RPF;
	rpf->entity.index = index;

	sprintf(name, "rpf.%u", index);
	ret = vsp1_entity_init(vsp1, &rpf->entity, name, 2, &rpf_ops,
			       MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER);
	if (ret < 0)
		return ERR_PTR(ret);

	/* Initialize the control handler. */
	ret = vsp1_rwpf_init_ctrls(rpf, 0);
	if (ret < 0) {
		dev_err(vsp1->dev, "rpf%u: failed to initialize controls\n",
			index);
		goto error;
	}

	v4l2_ctrl_handler_setup(&rpf->ctrls);

	return rpf;

error:
	vsp1_entity_destroy(&rpf->entity);
	return ERR_PTR(ret);
}
