// SPDX-License-Identifier: GPL-2.0
/*
 * R-Car Display Unit Writeback Support
 *
 * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 */

#include <drm/drm_atomic_helper.h>
#include <drm/drm_device.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_writeback.h>

#include "rcar_du_crtc.h"
#include "rcar_du_drv.h"
#include "rcar_du_kms.h"
#include "rcar_du_writeback.h"

/**
 * struct rcar_du_wb_conn_state - Driver-specific writeback connector state
 * @state: base DRM connector state
 * @format: format of the writeback framebuffer
 */
struct rcar_du_wb_conn_state {
	struct drm_connector_state state;
	const struct rcar_du_format_info *format;
};

#define to_rcar_wb_conn_state(s) \
	container_of(s, struct rcar_du_wb_conn_state, state)

/**
 * struct rcar_du_wb_job - Driver-private data for writeback jobs
 * @sg_tables: scatter-gather tables for the framebuffer memory
 */
struct rcar_du_wb_job {
	struct sg_table sg_tables[3];
};

static int rcar_du_wb_conn_get_modes(struct drm_connector *connector)
{
	struct drm_device *dev = connector->dev;

	return drm_add_modes_noedid(connector, dev->mode_config.max_width,
				    dev->mode_config.max_height);
}

static int rcar_du_wb_prepare_job(struct drm_writeback_connector *connector,
				  struct drm_writeback_job *job)
{
	struct rcar_du_crtc *rcrtc = wb_to_rcar_crtc(connector);
	struct rcar_du_wb_job *rjob;
	int ret;

	if (!job->fb)
		return 0;

	rjob = kzalloc(sizeof(*rjob), GFP_KERNEL);
	if (!rjob)
		return -ENOMEM;

	/* Map the framebuffer to the VSP. */
	ret = rcar_du_vsp_map_fb(rcrtc->vsp, job->fb, rjob->sg_tables);
	if (ret < 0) {
		kfree(rjob);
		return ret;
	}

	job->priv = rjob;
	return 0;
}

static void rcar_du_wb_cleanup_job(struct drm_writeback_connector *connector,
				   struct drm_writeback_job *job)
{
	struct rcar_du_crtc *rcrtc = wb_to_rcar_crtc(connector);
	struct rcar_du_wb_job *rjob = job->priv;

	if (!job->fb)
		return;

	rcar_du_vsp_unmap_fb(rcrtc->vsp, job->fb, rjob->sg_tables);
	kfree(rjob);
}

static const struct drm_connector_helper_funcs rcar_du_wb_conn_helper_funcs = {
	.get_modes = rcar_du_wb_conn_get_modes,
	.prepare_writeback_job = rcar_du_wb_prepare_job,
	.cleanup_writeback_job = rcar_du_wb_cleanup_job,
};

static struct drm_connector_state *
rcar_du_wb_conn_duplicate_state(struct drm_connector *connector)
{
	struct rcar_du_wb_conn_state *copy;

	if (WARN_ON(!connector->state))
		return NULL;

	copy = kzalloc(sizeof(*copy), GFP_KERNEL);
	if (!copy)
		return NULL;

	__drm_atomic_helper_connector_duplicate_state(connector, &copy->state);

	return &copy->state;
}

static void rcar_du_wb_conn_destroy_state(struct drm_connector *connector,
					  struct drm_connector_state *state)
{
	__drm_atomic_helper_connector_destroy_state(state);
	kfree(to_rcar_wb_conn_state(state));
}

static void rcar_du_wb_conn_reset(struct drm_connector *connector)
{
	struct rcar_du_wb_conn_state *state;

	if (connector->state) {
		rcar_du_wb_conn_destroy_state(connector, connector->state);
		connector->state = NULL;
	}

	state = kzalloc(sizeof(*state), GFP_KERNEL);
	if (state == NULL)
		return;

	__drm_atomic_helper_connector_reset(connector, &state->state);
}

static const struct drm_connector_funcs rcar_du_wb_conn_funcs = {
	.reset = rcar_du_wb_conn_reset,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
	.atomic_duplicate_state = rcar_du_wb_conn_duplicate_state,
	.atomic_destroy_state = rcar_du_wb_conn_destroy_state,
};

static int rcar_du_wb_enc_atomic_check(struct drm_encoder *encoder,
				       struct drm_crtc_state *crtc_state,
				       struct drm_connector_state *conn_state)
{
	struct rcar_du_wb_conn_state *wb_state =
		to_rcar_wb_conn_state(conn_state);
	const struct drm_display_mode *mode = &crtc_state->mode;
	struct drm_device *dev = encoder->dev;
	struct drm_framebuffer *fb;

	if (!conn_state->writeback_job)
		return 0;

	fb = conn_state->writeback_job->fb;

	/*
	 * Verify that the framebuffer format is supported and that its size
	 * matches the current mode.
	 */
	if (fb->width != mode->hdisplay || fb->height != mode->vdisplay) {
		dev_dbg(dev->dev, "%s: invalid framebuffer size %ux%u\n",
			__func__, fb->width, fb->height);
		return -EINVAL;
	}

	wb_state->format = rcar_du_format_info(fb->format->format);
	if (wb_state->format == NULL) {
		dev_dbg(dev->dev, "%s: unsupported format %08x\n", __func__,
			fb->format->format);
		return -EINVAL;
	}

	return 0;
}

static const struct drm_encoder_helper_funcs rcar_du_wb_enc_helper_funcs = {
	.atomic_check = rcar_du_wb_enc_atomic_check,
};

/*
 * Only RGB formats are currently supported as the VSP outputs RGB to the DU
 * and can't convert to YUV separately for writeback.
 */
static const u32 writeback_formats[] = {
	DRM_FORMAT_RGB332,
	DRM_FORMAT_ARGB4444,
	DRM_FORMAT_XRGB4444,
	DRM_FORMAT_ARGB1555,
	DRM_FORMAT_XRGB1555,
	DRM_FORMAT_RGB565,
	DRM_FORMAT_BGR888,
	DRM_FORMAT_RGB888,
	DRM_FORMAT_BGRA8888,
	DRM_FORMAT_BGRX8888,
	DRM_FORMAT_ARGB8888,
	DRM_FORMAT_XRGB8888,
};

int rcar_du_writeback_init(struct rcar_du_device *rcdu,
			   struct rcar_du_crtc *rcrtc)
{
	struct drm_writeback_connector *wb_conn = &rcrtc->writeback;

	drm_connector_helper_add(&wb_conn->base,
				 &rcar_du_wb_conn_helper_funcs);

	return drm_writeback_connector_init(&rcdu->ddev, wb_conn,
					    &rcar_du_wb_conn_funcs,
					    &rcar_du_wb_enc_helper_funcs,
					    writeback_formats,
					    ARRAY_SIZE(writeback_formats),
					    1 << drm_crtc_index(&rcrtc->crtc));
}

void rcar_du_writeback_setup(struct rcar_du_crtc *rcrtc,
			     struct vsp1_du_writeback_config *cfg)
{
	struct rcar_du_wb_conn_state *wb_state;
	struct drm_connector_state *state;
	struct rcar_du_wb_job *rjob;
	struct drm_framebuffer *fb;
	unsigned int i;

	state = rcrtc->writeback.base.state;
	if (!state || !state->writeback_job)
		return;

	fb = state->writeback_job->fb;
	rjob = state->writeback_job->priv;
	wb_state = to_rcar_wb_conn_state(state);

	cfg->pixelformat = wb_state->format->v4l2;
	cfg->pitch = fb->pitches[0];

	for (i = 0; i < wb_state->format->planes; ++i)
		cfg->mem[i] = sg_dma_address(rjob->sg_tables[i].sgl)
			    + fb->offsets[i];

	drm_writeback_queue_job(&rcrtc->writeback, state);
}

void rcar_du_writeback_complete(struct rcar_du_crtc *rcrtc)
{
	drm_writeback_signal_completion(&rcrtc->writeback, 0);
}
