// SPDX-License-Identifier: GPL-2.0+
/*
 * vsp1_hgo.c  --  R-Car VSP1 Histogram Generator 1D
 *
 * Copyright (C) 2016 Renesas Electronics Corporation
 *
 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
 */

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

#include <media/v4l2-subdev.h>
#include <media/videobuf2-vmalloc.h>

#include "vsp1.h"
#include "vsp1_dl.h"
#include "vsp1_hgo.h"

#define HGO_DATA_SIZE				((2 + 256) * 4)

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

static inline u32 vsp1_hgo_read(struct vsp1_hgo *hgo, u32 reg)
{
	return vsp1_read(hgo->histo.entity.vsp1, reg);
}

static inline void vsp1_hgo_write(struct vsp1_hgo *hgo,
				  struct vsp1_dl_body *dlb, u32 reg, u32 data)
{
	vsp1_dl_body_write(dlb, reg, data);
}

/* -----------------------------------------------------------------------------
 * Frame End Handler
 */

void vsp1_hgo_frame_end(struct vsp1_entity *entity)
{
	struct vsp1_hgo *hgo = to_hgo(&entity->subdev);
	struct vsp1_histogram_buffer *buf;
	unsigned int i;
	size_t size;
	u32 *data;

	buf = vsp1_histogram_buffer_get(&hgo->histo);
	if (!buf)
		return;

	data = buf->addr;

	if (hgo->num_bins == 256) {
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_MAXMIN);
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_SUM);

		for (i = 0; i < 256; ++i) {
			vsp1_write(hgo->histo.entity.vsp1,
				   VI6_HGO_EXT_HIST_ADDR, i);
			*data++ = vsp1_hgo_read(hgo, VI6_HGO_EXT_HIST_DATA);
		}

		size = (2 + 256) * sizeof(u32);
	} else if (hgo->max_rgb) {
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_MAXMIN);
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_SUM);

		for (i = 0; i < 64; ++i)
			*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_HISTO(i));

		size = (2 + 64) * sizeof(u32);
	} else {
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_R_MAXMIN);
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_MAXMIN);
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_B_MAXMIN);

		*data++ = vsp1_hgo_read(hgo, VI6_HGO_R_SUM);
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_G_SUM);
		*data++ = vsp1_hgo_read(hgo, VI6_HGO_B_SUM);

		for (i = 0; i < 64; ++i) {
			data[i] = vsp1_hgo_read(hgo, VI6_HGO_R_HISTO(i));
			data[i+64] = vsp1_hgo_read(hgo, VI6_HGO_G_HISTO(i));
			data[i+128] = vsp1_hgo_read(hgo, VI6_HGO_B_HISTO(i));
		}

		size = (6 + 64 * 3) * sizeof(u32);
	}

	vsp1_histogram_buffer_complete(&hgo->histo, buf, size);
}

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

#define V4L2_CID_VSP1_HGO_MAX_RGB		(V4L2_CID_USER_BASE | 0x1001)
#define V4L2_CID_VSP1_HGO_NUM_BINS		(V4L2_CID_USER_BASE | 0x1002)

static const struct v4l2_ctrl_config hgo_max_rgb_control = {
	.id = V4L2_CID_VSP1_HGO_MAX_RGB,
	.name = "Maximum RGB Mode",
	.type = V4L2_CTRL_TYPE_BOOLEAN,
	.min = 0,
	.max = 1,
	.def = 0,
	.step = 1,
	.flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
};

static const s64 hgo_num_bins[] = {
	64, 256,
};

static const struct v4l2_ctrl_config hgo_num_bins_control = {
	.id = V4L2_CID_VSP1_HGO_NUM_BINS,
	.name = "Number of Bins",
	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
	.min = 0,
	.max = 1,
	.def = 0,
	.qmenu_int = hgo_num_bins,
	.flags = V4L2_CTRL_FLAG_MODIFY_LAYOUT,
};

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

static void hgo_configure_stream(struct vsp1_entity *entity,
				 struct vsp1_pipeline *pipe,
				 struct vsp1_dl_list *dl,
				 struct vsp1_dl_body *dlb)
{
	struct vsp1_hgo *hgo = to_hgo(&entity->subdev);
	struct v4l2_rect *compose;
	struct v4l2_rect *crop;
	unsigned int hratio;
	unsigned int vratio;

	crop = vsp1_entity_get_pad_selection(entity, entity->state,
					     HISTO_PAD_SINK, V4L2_SEL_TGT_CROP);
	compose = vsp1_entity_get_pad_selection(entity, entity->state,
						HISTO_PAD_SINK,
						V4L2_SEL_TGT_COMPOSE);

	vsp1_hgo_write(hgo, dlb, VI6_HGO_REGRST, VI6_HGO_REGRST_RCLEA);

	vsp1_hgo_write(hgo, dlb, VI6_HGO_OFFSET,
		       (crop->left << VI6_HGO_OFFSET_HOFFSET_SHIFT) |
		       (crop->top << VI6_HGO_OFFSET_VOFFSET_SHIFT));
	vsp1_hgo_write(hgo, dlb, VI6_HGO_SIZE,
		       (crop->width << VI6_HGO_SIZE_HSIZE_SHIFT) |
		       (crop->height << VI6_HGO_SIZE_VSIZE_SHIFT));

	mutex_lock(hgo->ctrls.handler.lock);
	hgo->max_rgb = hgo->ctrls.max_rgb->cur.val;
	if (hgo->ctrls.num_bins)
		hgo->num_bins = hgo_num_bins[hgo->ctrls.num_bins->cur.val];
	mutex_unlock(hgo->ctrls.handler.lock);

	hratio = crop->width * 2 / compose->width / 3;
	vratio = crop->height * 2 / compose->height / 3;
	vsp1_hgo_write(hgo, dlb, VI6_HGO_MODE,
		       (hgo->num_bins == 256 ? VI6_HGO_MODE_STEP : 0) |
		       (hgo->max_rgb ? VI6_HGO_MODE_MAXRGB : 0) |
		       (hratio << VI6_HGO_MODE_HRATIO_SHIFT) |
		       (vratio << VI6_HGO_MODE_VRATIO_SHIFT));
}

static const struct vsp1_entity_operations hgo_entity_ops = {
	.configure_stream = hgo_configure_stream,
	.destroy = vsp1_histogram_destroy,
};

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

static const unsigned int hgo_mbus_formats[] = {
	MEDIA_BUS_FMT_AYUV8_1X32,
	MEDIA_BUS_FMT_ARGB8888_1X32,
	MEDIA_BUS_FMT_AHSV8888_1X32,
};

struct vsp1_hgo *vsp1_hgo_create(struct vsp1_device *vsp1)
{
	struct vsp1_hgo *hgo;
	int ret;

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

	/* Initialize the control handler. */
	v4l2_ctrl_handler_init(&hgo->ctrls.handler,
			       vsp1->info->gen >= 3 ? 2 : 1);
	hgo->ctrls.max_rgb = v4l2_ctrl_new_custom(&hgo->ctrls.handler,
						  &hgo_max_rgb_control, NULL);
	if (vsp1->info->gen >= 3)
		hgo->ctrls.num_bins =
			v4l2_ctrl_new_custom(&hgo->ctrls.handler,
					     &hgo_num_bins_control, NULL);

	hgo->max_rgb = false;
	hgo->num_bins = 64;

	hgo->histo.entity.subdev.ctrl_handler = &hgo->ctrls.handler;

	/* Initialize the video device and queue for statistics data. */
	ret = vsp1_histogram_init(vsp1, &hgo->histo, VSP1_ENTITY_HGO, "hgo",
				  &hgo_entity_ops, hgo_mbus_formats,
				  ARRAY_SIZE(hgo_mbus_formats),
				  HGO_DATA_SIZE, V4L2_META_FMT_VSP1_HGO);
	if (ret < 0) {
		vsp1_entity_destroy(&hgo->histo.entity);
		return ERR_PTR(ret);
	}

	return hgo;
}
