// SPDX-License-Identifier: GPL-2.0
/*
 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
 * Author: James.Qian.Wang <james.qian.wang@arm.com>
 *
 */
#include <drm/drm_framebuffer.h>
#include "komeda_dev.h"
#include "komeda_kms.h"

static int
komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
			 struct drm_connector_state *conn_st,
			 struct komeda_crtc_state *kcrtc_st,
			 struct komeda_data_flow_cfg *dflow)
{
	struct drm_framebuffer *fb = conn_st->writeback_job->fb;

	memset(dflow, 0, sizeof(*dflow));

	dflow->out_w = fb->width;
	dflow->out_h = fb->height;

	/* the write back data comes from the compiz */
	pipeline_composition_size(kcrtc_st, &dflow->in_w, &dflow->in_h);
	dflow->input.component = &wb_layer->base.pipeline->compiz->base;
	/* compiz doesn't output alpha */
	dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;
	dflow->rot = DRM_MODE_ROTATE_0;

	komeda_complete_data_flow_cfg(wb_layer, dflow, fb);

	return 0;
}

static int
komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
			       struct drm_crtc_state *crtc_st,
			       struct drm_connector_state *conn_st)
{
	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
	struct drm_writeback_job *writeback_job = conn_st->writeback_job;
	struct komeda_layer *wb_layer;
	struct komeda_data_flow_cfg dflow;
	int err;

	if (!writeback_job)
		return 0;

	if (!crtc_st->active) {
		DRM_DEBUG_ATOMIC("Cannot write the composition result out on a inactive CRTC.\n");
		return -EINVAL;
	}

	wb_layer = to_kconn(to_wb_conn(conn_st->connector))->wb_layer;

	/*
	 * No need for a full modested when the only connector changed is the
	 * writeback connector.
	 */
	if (crtc_st->connectors_changed &&
	    is_only_changed_connector(crtc_st, conn_st->connector))
		crtc_st->connectors_changed = false;

	err = komeda_wb_init_data_flow(wb_layer, conn_st, kcrtc_st, &dflow);
	if (err)
		return err;

	if (dflow.en_split)
		err = komeda_build_wb_split_data_flow(wb_layer,
				conn_st, kcrtc_st, &dflow);
	else
		err = komeda_build_wb_data_flow(wb_layer,
				conn_st, kcrtc_st, &dflow);

	return err;
}

static const struct drm_encoder_helper_funcs komeda_wb_encoder_helper_funcs = {
	.atomic_check = komeda_wb_encoder_atomic_check,
};

static int
komeda_wb_connector_get_modes(struct drm_connector *connector)
{
	return 0;
}

static enum drm_mode_status
komeda_wb_connector_mode_valid(struct drm_connector *connector,
			       struct drm_display_mode *mode)
{
	struct drm_device *dev = connector->dev;
	struct drm_mode_config *mode_config = &dev->mode_config;
	int w = mode->hdisplay, h = mode->vdisplay;

	if ((w < mode_config->min_width) || (w > mode_config->max_width))
		return MODE_BAD_HVALUE;

	if ((h < mode_config->min_height) || (h > mode_config->max_height))
		return MODE_BAD_VVALUE;

	return MODE_OK;
}

static const struct drm_connector_helper_funcs komeda_wb_conn_helper_funcs = {
	.get_modes	= komeda_wb_connector_get_modes,
	.mode_valid	= komeda_wb_connector_mode_valid,
};

static enum drm_connector_status
komeda_wb_connector_detect(struct drm_connector *connector, bool force)
{
	return connector_status_connected;
}

static int
komeda_wb_connector_fill_modes(struct drm_connector *connector,
			       uint32_t maxX, uint32_t maxY)
{
	return 0;
}

static void komeda_wb_connector_destroy(struct drm_connector *connector)
{
	drm_connector_cleanup(connector);
	kfree(to_kconn(to_wb_conn(connector)));
}

static const struct drm_connector_funcs komeda_wb_connector_funcs = {
	.reset			= drm_atomic_helper_connector_reset,
	.detect			= komeda_wb_connector_detect,
	.fill_modes		= komeda_wb_connector_fill_modes,
	.destroy		= komeda_wb_connector_destroy,
	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
};

static int komeda_wb_connector_add(struct komeda_kms_dev *kms,
				   struct komeda_crtc *kcrtc)
{
	struct komeda_dev *mdev = kms->base.dev_private;
	struct komeda_wb_connector *kwb_conn;
	struct drm_writeback_connector *wb_conn;
	struct drm_display_info *info;
	u32 *formats, n_formats = 0;
	int err;

	if (!kcrtc->master->wb_layer)
		return 0;

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

	kwb_conn->wb_layer = kcrtc->master->wb_layer;

	wb_conn = &kwb_conn->base;

	formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
					       kwb_conn->wb_layer->layer_type,
					       &n_formats);

	err = drm_writeback_connector_init(&kms->base, wb_conn,
					   &komeda_wb_connector_funcs,
					   &komeda_wb_encoder_helper_funcs,
					   formats, n_formats,
					   BIT(drm_crtc_index(&kcrtc->base)));
	komeda_put_fourcc_list(formats);
	if (err) {
		kfree(kwb_conn);
		return err;
	}

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

	info = &kwb_conn->base.base.display_info;
	info->bpc = __fls(kcrtc->master->improc->supported_color_depths);
	info->color_formats = kcrtc->master->improc->supported_color_formats;

	kcrtc->wb_conn = kwb_conn;

	return 0;
}

int komeda_kms_add_wb_connectors(struct komeda_kms_dev *kms,
				 struct komeda_dev *mdev)
{
	int i, err;

	for (i = 0; i < kms->n_crtcs; i++) {
		err = komeda_wb_connector_add(kms, &kms->crtcs[i]);
		if (err)
			return err;
	}

	return 0;
}
