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

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

#include <media/media-entity.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>

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

void vsp1_entity_route_setup(struct vsp1_entity *entity,
			     struct vsp1_pipeline *pipe,
			     struct vsp1_dl_body *dlb)
{
	struct vsp1_entity *source;
	u32 route;

	if (entity->type == VSP1_ENTITY_HGO) {
		u32 smppt;

		/*
		 * The HGO is a special case, its routing is configured on the
		 * sink pad.
		 */
		source = entity->sources[0];
		smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
		      | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);

		vsp1_dl_body_write(dlb, VI6_DPR_HGO_SMPPT, smppt);
		return;
	} else if (entity->type == VSP1_ENTITY_HGT) {
		u32 smppt;

		/*
		 * The HGT is a special case, its routing is configured on the
		 * sink pad.
		 */
		source = entity->sources[0];
		smppt = (pipe->output->entity.index << VI6_DPR_SMPPT_TGW_SHIFT)
		      | (source->route->output << VI6_DPR_SMPPT_PT_SHIFT);

		vsp1_dl_body_write(dlb, VI6_DPR_HGT_SMPPT, smppt);
		return;
	}

	source = entity;
	if (source->route->reg == 0)
		return;

	route = source->sink->route->inputs[source->sink_pad];
	/*
	 * The ILV and BRS share the same data path route. The extra BRSSEL bit
	 * selects between the ILV and BRS.
	 */
	if (source->type == VSP1_ENTITY_BRS)
		route |= VI6_DPR_ROUTE_BRSSEL;
	vsp1_dl_body_write(dlb, source->route->reg, route);
}

void vsp1_entity_configure_stream(struct vsp1_entity *entity,
				  struct vsp1_pipeline *pipe,
				  struct vsp1_dl_list *dl,
				  struct vsp1_dl_body *dlb)
{
	if (entity->ops->configure_stream)
		entity->ops->configure_stream(entity, pipe, dl, dlb);
}

void vsp1_entity_configure_frame(struct vsp1_entity *entity,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_list *dl,
				 struct vsp1_dl_body *dlb)
{
	if (entity->ops->configure_frame)
		entity->ops->configure_frame(entity, pipe, dl, dlb);
}

void vsp1_entity_configure_partition(struct vsp1_entity *entity,
				     struct vsp1_pipeline *pipe,
				     struct vsp1_dl_list *dl,
				     struct vsp1_dl_body *dlb)
{
	if (entity->ops->configure_partition)
		entity->ops->configure_partition(entity, pipe, dl, dlb);
}

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

/**
 * vsp1_entity_get_pad_config - Get the pad configuration for an entity
 * @entity: the entity
 * @cfg: the TRY pad configuration
 * @which: configuration selector (ACTIVE or TRY)
 *
 * When called with which set to V4L2_SUBDEV_FORMAT_ACTIVE the caller must hold
 * the entity lock to access the returned configuration.
 *
 * Return the pad configuration requested by the which argument. The TRY
 * configuration is passed explicitly to the function through the cfg argument
 * and simply returned when requested. The ACTIVE configuration comes from the
 * entity structure.
 */
struct v4l2_subdev_pad_config *
vsp1_entity_get_pad_config(struct vsp1_entity *entity,
			   struct v4l2_subdev_pad_config *cfg,
			   enum v4l2_subdev_format_whence which)
{
	switch (which) {
	case V4L2_SUBDEV_FORMAT_ACTIVE:
		return entity->config;
	case V4L2_SUBDEV_FORMAT_TRY:
	default:
		return cfg;
	}
}

/**
 * vsp1_entity_get_pad_format - Get a pad format from storage for an entity
 * @entity: the entity
 * @cfg: the configuration storage
 * @pad: the pad number
 *
 * Return the format stored in the given configuration for an entity's pad. The
 * configuration can be an ACTIVE or TRY configuration.
 */
struct v4l2_mbus_framefmt *
vsp1_entity_get_pad_format(struct vsp1_entity *entity,
			   struct v4l2_subdev_pad_config *cfg,
			   unsigned int pad)
{
	return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
}

/**
 * vsp1_entity_get_pad_selection - Get a pad selection from storage for entity
 * @entity: the entity
 * @cfg: the configuration storage
 * @pad: the pad number
 * @target: the selection target
 *
 * Return the selection rectangle stored in the given configuration for an
 * entity's pad. The configuration can be an ACTIVE or TRY configuration. The
 * selection target can be COMPOSE or CROP.
 */
struct v4l2_rect *
vsp1_entity_get_pad_selection(struct vsp1_entity *entity,
			      struct v4l2_subdev_pad_config *cfg,
			      unsigned int pad, unsigned int target)
{
	switch (target) {
	case V4L2_SEL_TGT_COMPOSE:
		return v4l2_subdev_get_try_compose(&entity->subdev, cfg, pad);
	case V4L2_SEL_TGT_CROP:
		return v4l2_subdev_get_try_crop(&entity->subdev, cfg, pad);
	default:
		return NULL;
	}
}

/*
 * vsp1_entity_init_cfg - Initialize formats on all pads
 * @subdev: V4L2 subdevice
 * @cfg: V4L2 subdev pad configuration
 *
 * Initialize all pad formats with default values in the given pad config. This
 * function can be used as a handler for the subdev pad::init_cfg operation.
 */
int vsp1_entity_init_cfg(struct v4l2_subdev *subdev,
			 struct v4l2_subdev_pad_config *cfg)
{
	struct v4l2_subdev_format format;
	unsigned int pad;

	for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) {
		memset(&format, 0, sizeof(format));

		format.pad = pad;
		format.which = cfg ? V4L2_SUBDEV_FORMAT_TRY
			     : V4L2_SUBDEV_FORMAT_ACTIVE;

		v4l2_subdev_call(subdev, pad, set_fmt, cfg, &format);
	}

	return 0;
}

/*
 * vsp1_subdev_get_pad_format - Subdev pad get_fmt handler
 * @subdev: V4L2 subdevice
 * @cfg: V4L2 subdev pad configuration
 * @fmt: V4L2 subdev format
 *
 * This function implements the subdev get_fmt pad operation. It can be used as
 * a direct drop-in for the operation handler.
 */
int vsp1_subdev_get_pad_format(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_format *fmt)
{
	struct vsp1_entity *entity = to_vsp1_entity(subdev);
	struct v4l2_subdev_pad_config *config;

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

	mutex_lock(&entity->lock);
	fmt->format = *vsp1_entity_get_pad_format(entity, config, fmt->pad);
	mutex_unlock(&entity->lock);

	return 0;
}

/*
 * vsp1_subdev_enum_mbus_code - Subdev pad enum_mbus_code handler
 * @subdev: V4L2 subdevice
 * @cfg: V4L2 subdev pad configuration
 * @code: Media bus code enumeration
 * @codes: Array of supported media bus codes
 * @ncodes: Number of supported media bus codes
 *
 * This function implements the subdev enum_mbus_code pad operation for entities
 * that do not support format conversion. It enumerates the given supported
 * media bus codes on the sink pad and reports a source pad format identical to
 * the sink pad.
 */
int vsp1_subdev_enum_mbus_code(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_mbus_code_enum *code,
			       const unsigned int *codes, unsigned int ncodes)
{
	struct vsp1_entity *entity = to_vsp1_entity(subdev);

	if (code->pad == 0) {
		if (code->index >= ncodes)
			return -EINVAL;

		code->code = codes[code->index];
	} else {
		struct v4l2_subdev_pad_config *config;
		struct v4l2_mbus_framefmt *format;

		/*
		 * The entity can't perform format conversion, the sink format
		 * is always identical to the source format.
		 */
		if (code->index)
			return -EINVAL;

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

		mutex_lock(&entity->lock);
		format = vsp1_entity_get_pad_format(entity, config, 0);
		code->code = format->code;
		mutex_unlock(&entity->lock);
	}

	return 0;
}

/*
 * vsp1_subdev_enum_frame_size - Subdev pad enum_frame_size handler
 * @subdev: V4L2 subdevice
 * @cfg: V4L2 subdev pad configuration
 * @fse: Frame size enumeration
 * @min_width: Minimum image width
 * @min_height: Minimum image height
 * @max_width: Maximum image width
 * @max_height: Maximum image height
 *
 * This function implements the subdev enum_frame_size pad operation for
 * entities that do not support scaling or cropping. It reports the given
 * minimum and maximum frame width and height on the sink pad, and a fixed
 * source pad size identical to the sink pad.
 */
int vsp1_subdev_enum_frame_size(struct v4l2_subdev *subdev,
				struct v4l2_subdev_pad_config *cfg,
				struct v4l2_subdev_frame_size_enum *fse,
				unsigned int min_width, unsigned int min_height,
				unsigned int max_width, unsigned int max_height)
{
	struct vsp1_entity *entity = to_vsp1_entity(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	int ret = 0;

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

	format = vsp1_entity_get_pad_format(entity, config, fse->pad);

	mutex_lock(&entity->lock);

	if (fse->index || fse->code != format->code) {
		ret = -EINVAL;
		goto done;
	}

	if (fse->pad == 0) {
		fse->min_width = min_width;
		fse->max_width = max_width;
		fse->min_height = min_height;
		fse->max_height = max_height;
	} else {
		/*
		 * The size on the source pad are fixed and always identical to
		 * the size on the sink pad.
		 */
		fse->min_width = format->width;
		fse->max_width = format->width;
		fse->min_height = format->height;
		fse->max_height = format->height;
	}

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

/*
 * vsp1_subdev_set_pad_format - Subdev pad set_fmt handler
 * @subdev: V4L2 subdevice
 * @cfg: V4L2 subdev pad configuration
 * @fmt: V4L2 subdev format
 * @codes: Array of supported media bus codes
 * @ncodes: Number of supported media bus codes
 * @min_width: Minimum image width
 * @min_height: Minimum image height
 * @max_width: Maximum image width
 * @max_height: Maximum image height
 *
 * This function implements the subdev set_fmt pad operation for entities that
 * do not support scaling or cropping. It defaults to the first supplied media
 * bus code if the requested code isn't supported, clamps the size to the
 * supplied minimum and maximum, and propagates the sink pad format to the
 * source pad.
 */
int vsp1_subdev_set_pad_format(struct v4l2_subdev *subdev,
			       struct v4l2_subdev_pad_config *cfg,
			       struct v4l2_subdev_format *fmt,
			       const unsigned int *codes, unsigned int ncodes,
			       unsigned int min_width, unsigned int min_height,
			       unsigned int max_width, unsigned int max_height)
{
	struct vsp1_entity *entity = to_vsp1_entity(subdev);
	struct v4l2_subdev_pad_config *config;
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *selection;
	unsigned int i;
	int ret = 0;

	mutex_lock(&entity->lock);

	config = vsp1_entity_get_pad_config(entity, cfg, fmt->which);
	if (!config) {
		ret = -EINVAL;
		goto done;
	}

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

	if (fmt->pad == entity->source_pad) {
		/* The output format can't be modified. */
		fmt->format = *format;
		goto done;
	}

	/*
	 * Default to the first media bus code if the requested format is not
	 * supported.
	 */
	for (i = 0; i < ncodes; ++i) {
		if (fmt->format.code == codes[i])
			break;
	}

	format->code = i < ncodes ? codes[i] : codes[0];
	format->width = clamp_t(unsigned int, fmt->format.width,
				min_width, max_width);
	format->height = clamp_t(unsigned int, fmt->format.height,
				 min_height, max_height);
	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(entity, config, entity->source_pad);
	*format = fmt->format;

	/* Reset the crop and compose rectangles. */
	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
						  V4L2_SEL_TGT_CROP);
	selection->left = 0;
	selection->top = 0;
	selection->width = format->width;
	selection->height = format->height;

	selection = vsp1_entity_get_pad_selection(entity, config, fmt->pad,
						  V4L2_SEL_TGT_COMPOSE);
	selection->left = 0;
	selection->top = 0;
	selection->width = format->width;
	selection->height = format->height;

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

/* -----------------------------------------------------------------------------
 * Media Operations
 */

static inline struct vsp1_entity *
media_entity_to_vsp1_entity(struct media_entity *entity)
{
	return container_of(entity, struct vsp1_entity, subdev.entity);
}

static int vsp1_entity_link_setup_source(const struct media_pad *source_pad,
					 const struct media_pad *sink_pad,
					 u32 flags)
{
	struct vsp1_entity *source;

	source = media_entity_to_vsp1_entity(source_pad->entity);

	if (!source->route)
		return 0;

	if (flags & MEDIA_LNK_FL_ENABLED) {
		struct vsp1_entity *sink
			= media_entity_to_vsp1_entity(sink_pad->entity);

		/*
		 * Fan-out is limited to one for the normal data path plus
		 * optional HGO and HGT. We ignore the HGO and HGT here.
		 */
		if (sink->type != VSP1_ENTITY_HGO &&
		    sink->type != VSP1_ENTITY_HGT) {
			if (source->sink)
				return -EBUSY;
			source->sink = sink;
			source->sink_pad = sink_pad->index;
		}
	} else {
		source->sink = NULL;
		source->sink_pad = 0;
	}

	return 0;
}

static int vsp1_entity_link_setup_sink(const struct media_pad *source_pad,
				       const struct media_pad *sink_pad,
				       u32 flags)
{
	struct vsp1_entity *sink;
	struct vsp1_entity *source;

	sink = media_entity_to_vsp1_entity(sink_pad->entity);
	source = media_entity_to_vsp1_entity(source_pad->entity);

	if (flags & MEDIA_LNK_FL_ENABLED) {
		/* Fan-in is limited to one. */
		if (sink->sources[sink_pad->index])
			return -EBUSY;

		sink->sources[sink_pad->index] = source;
	} else {
		sink->sources[sink_pad->index] = NULL;
	}

	return 0;
}

int vsp1_entity_link_setup(struct media_entity *entity,
			   const struct media_pad *local,
			   const struct media_pad *remote, u32 flags)
{
	if (local->flags & MEDIA_PAD_FL_SOURCE)
		return vsp1_entity_link_setup_source(local, remote, flags);
	else
		return vsp1_entity_link_setup_sink(remote, local, flags);
}

/**
 * vsp1_entity_remote_pad - Find the pad at the remote end of a link
 * @pad: Pad at the local end of the link
 *
 * Search for a remote pad connected to the given pad by iterating over all
 * links originating or terminating at that pad until an enabled link is found.
 *
 * Our link setup implementation guarantees that the output fan-out will not be
 * higher than one for the data pipelines, except for the links to the HGO and
 * HGT that can be enabled in addition to a regular data link. When traversing
 * outgoing links this function ignores HGO and HGT entities and should thus be
 * used in place of the generic media_entity_remote_pad() function to traverse
 * data pipelines.
 *
 * Return a pointer to the pad at the remote end of the first found enabled
 * link, or NULL if no enabled link has been found.
 */
struct media_pad *vsp1_entity_remote_pad(struct media_pad *pad)
{
	struct media_link *link;

	list_for_each_entry(link, &pad->entity->links, list) {
		struct vsp1_entity *entity;

		if (!(link->flags & MEDIA_LNK_FL_ENABLED))
			continue;

		/* If we're the sink the source will never be an HGO or HGT. */
		if (link->sink == pad)
			return link->source;

		if (link->source != pad)
			continue;

		/* If the sink isn't a subdevice it can't be an HGO or HGT. */
		if (!is_media_entity_v4l2_subdev(link->sink->entity))
			return link->sink;

		entity = media_entity_to_vsp1_entity(link->sink->entity);
		if (entity->type != VSP1_ENTITY_HGO &&
		    entity->type != VSP1_ENTITY_HGT)
			return link->sink;
	}

	return NULL;

}

/* -----------------------------------------------------------------------------
 * Initialization
 */

#define VSP1_ENTITY_ROUTE(ent)						\
	{ VSP1_ENTITY_##ent, 0, VI6_DPR_##ent##_ROUTE,			\
	  { VI6_DPR_NODE_##ent }, VI6_DPR_NODE_##ent }

#define VSP1_ENTITY_ROUTE_RPF(idx)					\
	{ VSP1_ENTITY_RPF, idx, VI6_DPR_RPF_ROUTE(idx),			\
	  { 0, }, VI6_DPR_NODE_RPF(idx) }

#define VSP1_ENTITY_ROUTE_UDS(idx)					\
	{ VSP1_ENTITY_UDS, idx, VI6_DPR_UDS_ROUTE(idx),			\
	  { VI6_DPR_NODE_UDS(idx) }, VI6_DPR_NODE_UDS(idx) }

#define VSP1_ENTITY_ROUTE_UIF(idx)					\
	{ VSP1_ENTITY_UIF, idx, VI6_DPR_UIF_ROUTE(idx),			\
	  { VI6_DPR_NODE_UIF(idx) }, VI6_DPR_NODE_UIF(idx) }

#define VSP1_ENTITY_ROUTE_WPF(idx)					\
	{ VSP1_ENTITY_WPF, idx, 0,					\
	  { VI6_DPR_NODE_WPF(idx) }, VI6_DPR_NODE_WPF(idx) }

static const struct vsp1_route vsp1_routes[] = {
	{ VSP1_ENTITY_BRS, 0, VI6_DPR_ILV_BRS_ROUTE,
	  { VI6_DPR_NODE_BRS_IN(0), VI6_DPR_NODE_BRS_IN(1) }, 0 },
	{ VSP1_ENTITY_BRU, 0, VI6_DPR_BRU_ROUTE,
	  { VI6_DPR_NODE_BRU_IN(0), VI6_DPR_NODE_BRU_IN(1),
	    VI6_DPR_NODE_BRU_IN(2), VI6_DPR_NODE_BRU_IN(3),
	    VI6_DPR_NODE_BRU_IN(4) }, VI6_DPR_NODE_BRU_OUT },
	VSP1_ENTITY_ROUTE(CLU),
	{ VSP1_ENTITY_HGO, 0, 0, { 0, }, 0 },
	{ VSP1_ENTITY_HGT, 0, 0, { 0, }, 0 },
	VSP1_ENTITY_ROUTE(HSI),
	VSP1_ENTITY_ROUTE(HST),
	{ VSP1_ENTITY_LIF, 0, 0, { 0, }, 0 },
	{ VSP1_ENTITY_LIF, 1, 0, { 0, }, 0 },
	VSP1_ENTITY_ROUTE(LUT),
	VSP1_ENTITY_ROUTE_RPF(0),
	VSP1_ENTITY_ROUTE_RPF(1),
	VSP1_ENTITY_ROUTE_RPF(2),
	VSP1_ENTITY_ROUTE_RPF(3),
	VSP1_ENTITY_ROUTE_RPF(4),
	VSP1_ENTITY_ROUTE(SRU),
	VSP1_ENTITY_ROUTE_UDS(0),
	VSP1_ENTITY_ROUTE_UDS(1),
	VSP1_ENTITY_ROUTE_UDS(2),
	VSP1_ENTITY_ROUTE_UIF(0),	/* Named UIF4 in the documentation */
	VSP1_ENTITY_ROUTE_UIF(1),	/* Named UIF5 in the documentation */
	VSP1_ENTITY_ROUTE_WPF(0),
	VSP1_ENTITY_ROUTE_WPF(1),
	VSP1_ENTITY_ROUTE_WPF(2),
	VSP1_ENTITY_ROUTE_WPF(3),
};

int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity,
		     const char *name, unsigned int num_pads,
		     const struct v4l2_subdev_ops *ops, u32 function)
{
	struct v4l2_subdev *subdev;
	unsigned int i;
	int ret;

	for (i = 0; i < ARRAY_SIZE(vsp1_routes); ++i) {
		if (vsp1_routes[i].type == entity->type &&
		    vsp1_routes[i].index == entity->index) {
			entity->route = &vsp1_routes[i];
			break;
		}
	}

	if (i == ARRAY_SIZE(vsp1_routes))
		return -EINVAL;

	mutex_init(&entity->lock);

	entity->vsp1 = vsp1;
	entity->source_pad = num_pads - 1;

	/* Allocate and initialize pads. */
	entity->pads = devm_kcalloc(vsp1->dev,
				    num_pads, sizeof(*entity->pads),
				    GFP_KERNEL);
	if (entity->pads == NULL)
		return -ENOMEM;

	for (i = 0; i < num_pads - 1; ++i)
		entity->pads[i].flags = MEDIA_PAD_FL_SINK;

	entity->sources = devm_kcalloc(vsp1->dev, max(num_pads - 1, 1U),
				       sizeof(*entity->sources), GFP_KERNEL);
	if (entity->sources == NULL)
		return -ENOMEM;

	/* Single-pad entities only have a sink. */
	entity->pads[num_pads - 1].flags = num_pads > 1 ? MEDIA_PAD_FL_SOURCE
					 : MEDIA_PAD_FL_SINK;

	/* Initialize the media entity. */
	ret = media_entity_pads_init(&entity->subdev.entity, num_pads,
				     entity->pads);
	if (ret < 0)
		return ret;

	/* Initialize the V4L2 subdev. */
	subdev = &entity->subdev;
	v4l2_subdev_init(subdev, ops);

	subdev->entity.function = function;
	subdev->entity.ops = &vsp1->media_ops;
	subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	snprintf(subdev->name, sizeof(subdev->name), "%s %s",
		 dev_name(vsp1->dev), name);

	vsp1_entity_init_cfg(subdev, NULL);

	/*
	 * Allocate the pad configuration to store formats and selection
	 * rectangles.
	 */
	entity->config = v4l2_subdev_alloc_pad_config(&entity->subdev);
	if (entity->config == NULL) {
		media_entity_cleanup(&entity->subdev.entity);
		return -ENOMEM;
	}

	return 0;
}

void vsp1_entity_destroy(struct vsp1_entity *entity)
{
	if (entity->ops && entity->ops->destroy)
		entity->ops->destroy(entity);
	if (entity->subdev.ctrl_handler)
		v4l2_ctrl_handler_free(entity->subdev.ctrl_handler);
	v4l2_subdev_free_pad_config(entity->config);
	media_entity_cleanup(&entity->subdev.entity);
}
