// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for Renesas RZ/G2L CRU
 *
 * Copyright (C) 2022 Renesas Electronics Corp.
 */

#include "rzg2l-cru.h"

struct rzg2l_cru_ip_format {
	u32 code;
	unsigned int datatype;
	unsigned int bpp;
};

static const struct rzg2l_cru_ip_format rzg2l_cru_ip_formats[] = {
	{ .code = MEDIA_BUS_FMT_UYVY8_1X16,	.datatype = 0x1e, .bpp = 16 },
};

enum rzg2l_csi2_pads {
	RZG2L_CRU_IP_SINK = 0,
	RZG2L_CRU_IP_SOURCE,
};

static const struct rzg2l_cru_ip_format *rzg2l_cru_ip_code_to_fmt(unsigned int code)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(rzg2l_cru_ip_formats); i++)
		if (rzg2l_cru_ip_formats[i].code == code)
			return &rzg2l_cru_ip_formats[i];

	return NULL;
}

struct v4l2_mbus_framefmt *rzg2l_cru_ip_get_src_fmt(struct rzg2l_cru_dev *cru)
{
	struct v4l2_subdev_state *state;
	struct v4l2_mbus_framefmt *fmt;

	state = v4l2_subdev_lock_and_get_active_state(&cru->ip.subdev);
	fmt = v4l2_subdev_get_pad_format(&cru->ip.subdev, state, 1);
	v4l2_subdev_unlock_state(state);

	return fmt;
}

static int rzg2l_cru_ip_s_stream(struct v4l2_subdev *sd, int enable)
{
	struct rzg2l_cru_dev *cru;
	int s_stream_ret = 0;
	int ret;

	cru = v4l2_get_subdevdata(sd);

	if (!enable) {
		ret = v4l2_subdev_call(cru->ip.remote, video, s_stream, enable);
		if (ret)
			s_stream_ret = ret;

		ret = v4l2_subdev_call(cru->ip.remote, video, post_streamoff);
		if (ret == -ENOIOCTLCMD)
			ret = 0;
		if (ret && !s_stream_ret)
			s_stream_ret = ret;
		rzg2l_cru_stop_image_processing(cru);
	} else {
		ret = v4l2_subdev_call(cru->ip.remote, video, pre_streamon, 0);
		if (ret == -ENOIOCTLCMD)
			ret = 0;
		if (ret)
			return ret;

		ret = rzg2l_cru_start_image_processing(cru);
		if (ret) {
			v4l2_subdev_call(cru->ip.remote, video, post_streamoff);
			return ret;
		}

		rzg2l_cru_vclk_unprepare(cru);

		ret = v4l2_subdev_call(cru->ip.remote, video, s_stream, enable);
		if (ret == -ENOIOCTLCMD)
			ret = 0;
		if (!ret) {
			ret = rzg2l_cru_vclk_prepare(cru);
			if (!ret)
				return 0;
		} else {
			/* enable back vclk so that s_stream in error path disables it */
			if (rzg2l_cru_vclk_prepare(cru))
				dev_err(cru->dev, "Failed to enable vclk\n");
		}

		s_stream_ret = ret;

		v4l2_subdev_call(cru->ip.remote, video, post_streamoff);
		rzg2l_cru_stop_image_processing(cru);
	}

	return s_stream_ret;
}

static int rzg2l_cru_ip_set_format(struct v4l2_subdev *sd,
				   struct v4l2_subdev_state *state,
				   struct v4l2_subdev_format *fmt)
{
	struct v4l2_mbus_framefmt *src_format;
	struct v4l2_mbus_framefmt *sink_format;

	src_format = v4l2_subdev_get_pad_format(sd, state, RZG2L_CRU_IP_SOURCE);
	if (fmt->pad == RZG2L_CRU_IP_SOURCE) {
		fmt->format = *src_format;
		return 0;
	}

	sink_format = v4l2_subdev_get_pad_format(sd, state, fmt->pad);

	if (!rzg2l_cru_ip_code_to_fmt(fmt->format.code))
		sink_format->code = rzg2l_cru_ip_formats[0].code;
	else
		sink_format->code = fmt->format.code;

	sink_format->field = V4L2_FIELD_NONE;
	sink_format->colorspace = fmt->format.colorspace;
	sink_format->xfer_func = fmt->format.xfer_func;
	sink_format->ycbcr_enc = fmt->format.ycbcr_enc;
	sink_format->quantization = fmt->format.quantization;
	sink_format->width = clamp_t(u32, fmt->format.width,
				     RZG2L_CRU_MIN_INPUT_WIDTH, RZG2L_CRU_MAX_INPUT_WIDTH);
	sink_format->height = clamp_t(u32, fmt->format.height,
				      RZG2L_CRU_MIN_INPUT_HEIGHT, RZG2L_CRU_MAX_INPUT_HEIGHT);

	fmt->format = *sink_format;

	/* propagate format to source pad */
	*src_format = *sink_format;

	return 0;
}

static int rzg2l_cru_ip_enum_mbus_code(struct v4l2_subdev *sd,
				       struct v4l2_subdev_state *state,
				       struct v4l2_subdev_mbus_code_enum *code)
{
	if (code->index >= ARRAY_SIZE(rzg2l_cru_ip_formats))
		return -EINVAL;

	code->code = rzg2l_cru_ip_formats[code->index].code;
	return 0;
}

static int rzg2l_cru_ip_enum_frame_size(struct v4l2_subdev *sd,
					struct v4l2_subdev_state *state,
					struct v4l2_subdev_frame_size_enum *fse)
{
	if (fse->index != 0)
		return -EINVAL;

	if (fse->code != MEDIA_BUS_FMT_UYVY8_1X16)
		return -EINVAL;

	fse->min_width = RZG2L_CRU_MIN_INPUT_WIDTH;
	fse->min_height = RZG2L_CRU_MIN_INPUT_HEIGHT;
	fse->max_width = RZG2L_CRU_MAX_INPUT_WIDTH;
	fse->max_height = RZG2L_CRU_MAX_INPUT_HEIGHT;

	return 0;
}

static int rzg2l_cru_ip_init_config(struct v4l2_subdev *sd,
				    struct v4l2_subdev_state *sd_state)
{
	struct v4l2_subdev_format fmt = { .pad = RZG2L_CRU_IP_SINK, };

	fmt.format.width = RZG2L_CRU_MIN_INPUT_WIDTH;
	fmt.format.height = RZG2L_CRU_MIN_INPUT_HEIGHT;
	fmt.format.field = V4L2_FIELD_NONE;
	fmt.format.code = MEDIA_BUS_FMT_UYVY8_1X16;
	fmt.format.colorspace = V4L2_COLORSPACE_SRGB;
	fmt.format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
	fmt.format.quantization = V4L2_QUANTIZATION_DEFAULT;
	fmt.format.xfer_func = V4L2_XFER_FUNC_DEFAULT;

	return rzg2l_cru_ip_set_format(sd, sd_state, &fmt);
}

static const struct v4l2_subdev_video_ops rzg2l_cru_ip_video_ops = {
	.s_stream = rzg2l_cru_ip_s_stream,
};

static const struct v4l2_subdev_pad_ops rzg2l_cru_ip_pad_ops = {
	.enum_mbus_code = rzg2l_cru_ip_enum_mbus_code,
	.enum_frame_size = rzg2l_cru_ip_enum_frame_size,
	.init_cfg = rzg2l_cru_ip_init_config,
	.get_fmt = v4l2_subdev_get_fmt,
	.set_fmt = rzg2l_cru_ip_set_format,
};

static const struct v4l2_subdev_ops rzg2l_cru_ip_subdev_ops = {
	.video = &rzg2l_cru_ip_video_ops,
	.pad = &rzg2l_cru_ip_pad_ops,
};

static const struct media_entity_operations rzg2l_cru_ip_entity_ops = {
	.link_validate = v4l2_subdev_link_validate,
};

int rzg2l_cru_ip_subdev_register(struct rzg2l_cru_dev *cru)
{
	struct rzg2l_cru_ip *ip = &cru->ip;
	int ret;

	ip->subdev.dev = cru->dev;
	v4l2_subdev_init(&ip->subdev, &rzg2l_cru_ip_subdev_ops);
	v4l2_set_subdevdata(&ip->subdev, cru);
	snprintf(ip->subdev.name, sizeof(ip->subdev.name),
		 "cru-ip-%s", dev_name(cru->dev));
	ip->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;

	ip->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
	ip->subdev.entity.ops = &rzg2l_cru_ip_entity_ops;

	ip->pads[0].flags = MEDIA_PAD_FL_SINK;
	ip->pads[1].flags = MEDIA_PAD_FL_SOURCE;

	ret = media_entity_pads_init(&ip->subdev.entity, 2, ip->pads);
	if (ret)
		return ret;

	ret = v4l2_subdev_init_finalize(&ip->subdev);
	if (ret < 0)
		goto entity_cleanup;

	ret = v4l2_device_register_subdev(&cru->v4l2_dev, &ip->subdev);
	if (ret < 0)
		goto error_subdev;

	return 0;
error_subdev:
	v4l2_subdev_cleanup(&ip->subdev);
entity_cleanup:
	media_entity_cleanup(&ip->subdev.entity);

	return ret;
}

void rzg2l_cru_ip_subdev_unregister(struct rzg2l_cru_dev *cru)
{
	struct rzg2l_cru_ip *ip = &cru->ip;

	media_entity_cleanup(&ip->subdev.entity);
	v4l2_subdev_cleanup(&ip->subdev);
	v4l2_device_unregister_subdev(&ip->subdev);
}
