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

#include <drm/drm_print.h>

#include "komeda_dev.h"
#include "komeda_kms.h"
#include "komeda_pipeline.h"

/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
struct komeda_pipeline *
komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
		    const struct komeda_pipeline_funcs *funcs)
{
	struct komeda_pipeline *pipe;

	if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
		DRM_ERROR("Exceed max support %d pipelines.\n",
			  KOMEDA_MAX_PIPELINES);
		return ERR_PTR(-ENOSPC);
	}

	if (size < sizeof(*pipe)) {
		DRM_ERROR("Request pipeline size too small.\n");
		return ERR_PTR(-EINVAL);
	}

	pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
	if (!pipe)
		return ERR_PTR(-ENOMEM);

	pipe->mdev = mdev;
	pipe->id   = mdev->n_pipelines;
	pipe->funcs = funcs;

	mdev->pipelines[mdev->n_pipelines] = pipe;
	mdev->n_pipelines++;

	return pipe;
}

void komeda_pipeline_destroy(struct komeda_dev *mdev,
			     struct komeda_pipeline *pipe)
{
	struct komeda_component *c;
	int i;
	unsigned long avail_comps = pipe->avail_comps;

	for_each_set_bit(i, &avail_comps, 32) {
		c = komeda_pipeline_get_component(pipe, i);
		komeda_component_destroy(mdev, c);
	}

	clk_put(pipe->pxlclk);

	of_node_put(pipe->of_output_links[0]);
	of_node_put(pipe->of_output_links[1]);
	of_node_put(pipe->of_output_port);
	of_node_put(pipe->of_node);

	devm_kfree(mdev->dev, pipe);
}

static struct komeda_component **
komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
{
	struct komeda_dev *mdev = pipe->mdev;
	struct komeda_pipeline *temp = NULL;
	struct komeda_component **pos = NULL;

	switch (id) {
	case KOMEDA_COMPONENT_LAYER0:
	case KOMEDA_COMPONENT_LAYER1:
	case KOMEDA_COMPONENT_LAYER2:
	case KOMEDA_COMPONENT_LAYER3:
		pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
		break;
	case KOMEDA_COMPONENT_WB_LAYER:
		pos = to_cpos(pipe->wb_layer);
		break;
	case KOMEDA_COMPONENT_COMPIZ0:
	case KOMEDA_COMPONENT_COMPIZ1:
		temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
		if (!temp) {
			DRM_ERROR("compiz-%d doesn't exist.\n", id);
			return NULL;
		}
		pos = to_cpos(temp->compiz);
		break;
	case KOMEDA_COMPONENT_SCALER0:
	case KOMEDA_COMPONENT_SCALER1:
		pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
		break;
	case KOMEDA_COMPONENT_SPLITTER:
		pos = to_cpos(pipe->splitter);
		break;
	case KOMEDA_COMPONENT_MERGER:
		pos = to_cpos(pipe->merger);
		break;
	case KOMEDA_COMPONENT_IPS0:
	case KOMEDA_COMPONENT_IPS1:
		temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
		if (!temp) {
			DRM_ERROR("ips-%d doesn't exist.\n", id);
			return NULL;
		}
		pos = to_cpos(temp->improc);
		break;
	case KOMEDA_COMPONENT_TIMING_CTRLR:
		pos = to_cpos(pipe->ctrlr);
		break;
	default:
		pos = NULL;
		DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
		break;
	}

	return pos;
}

struct komeda_component *
komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
{
	struct komeda_component **pos = NULL;
	struct komeda_component *c = NULL;

	pos = komeda_pipeline_get_component_pos(pipe, id);
	if (pos)
		c = *pos;

	return c;
}

struct komeda_component *
komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
				    u32 comp_mask)
{
	struct komeda_component *c = NULL;
	unsigned long comp_mask_local = (unsigned long)comp_mask;
	int id;

	id = find_first_bit(&comp_mask_local, 32);
	if (id < 32)
		c = komeda_pipeline_get_component(pipe, id);

	return c;
}

static struct komeda_component *
komeda_component_pickup_input(struct komeda_component *c, u32 avail_comps)
{
	u32 avail_inputs = c->supported_inputs & (avail_comps);

	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
}

/** komeda_component_add - Add a component to &komeda_pipeline */
struct komeda_component *
komeda_component_add(struct komeda_pipeline *pipe,
		     size_t comp_sz, u32 id, u32 hw_id,
		     const struct komeda_component_funcs *funcs,
		     u8 max_active_inputs, u32 supported_inputs,
		     u8 max_active_outputs, u32 __iomem *reg,
		     const char *name_fmt, ...)
{
	struct komeda_component **pos;
	struct komeda_component *c;
	int idx, *num = NULL;

	if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
		WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
		     max_active_inputs);
		return ERR_PTR(-ENOSPC);
	}

	pos = komeda_pipeline_get_component_pos(pipe, id);
	if (!pos || (*pos))
		return ERR_PTR(-EINVAL);

	if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
		idx = id - KOMEDA_COMPONENT_LAYER0;
		num = &pipe->n_layers;
		if (idx != pipe->n_layers) {
			DRM_ERROR("please add Layer by id sequence.\n");
			return ERR_PTR(-EINVAL);
		}
	} else if (has_bit(id,  KOMEDA_PIPELINE_SCALERS)) {
		idx = id - KOMEDA_COMPONENT_SCALER0;
		num = &pipe->n_scalers;
		if (idx != pipe->n_scalers) {
			DRM_ERROR("please add Scaler by id sequence.\n");
			return ERR_PTR(-EINVAL);
		}
	}

	c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
	if (!c)
		return ERR_PTR(-ENOMEM);

	c->id = id;
	c->hw_id = hw_id;
	c->reg = reg;
	c->pipeline = pipe;
	c->max_active_inputs = max_active_inputs;
	c->max_active_outputs = max_active_outputs;
	c->supported_inputs = supported_inputs;
	c->funcs = funcs;

	if (name_fmt) {
		va_list args;

		va_start(args, name_fmt);
		vsnprintf(c->name, sizeof(c->name), name_fmt, args);
		va_end(args);
	}

	if (num)
		*num = *num + 1;

	pipe->avail_comps |= BIT(c->id);
	*pos = c;

	return c;
}

void komeda_component_destroy(struct komeda_dev *mdev,
			      struct komeda_component *c)
{
	devm_kfree(mdev->dev, c);
}

static void komeda_component_dump(struct komeda_component *c)
{
	if (!c)
		return;

	DRM_DEBUG("	%s: ID %d-0x%08lx.\n",
		  c->name, c->id, BIT(c->id));
	DRM_DEBUG("		max_active_inputs:%d, supported_inputs: 0x%08x.\n",
		  c->max_active_inputs, c->supported_inputs);
	DRM_DEBUG("		max_active_outputs:%d, supported_outputs: 0x%08x.\n",
		  c->max_active_outputs, c->supported_outputs);
}

void komeda_pipeline_dump(struct komeda_pipeline *pipe)
{
	struct komeda_component *c;
	int id;
	unsigned long avail_comps = pipe->avail_comps;

	DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
		 pipe->id, pipe->n_layers, pipe->n_scalers,
		 pipe->dual_link ? "dual-link" : "single-link");
	DRM_INFO("	output_link[0]: %s.\n",
		 pipe->of_output_links[0] ?
		 pipe->of_output_links[0]->full_name : "none");
	DRM_INFO("	output_link[1]: %s.\n",
		 pipe->of_output_links[1] ?
		 pipe->of_output_links[1]->full_name : "none");

	for_each_set_bit(id, &avail_comps, 32) {
		c = komeda_pipeline_get_component(pipe, id);

		komeda_component_dump(c);
	}
}

static void komeda_component_verify_inputs(struct komeda_component *c)
{
	struct komeda_pipeline *pipe = c->pipeline;
	struct komeda_component *input;
	int id;
	unsigned long supported_inputs = c->supported_inputs;

	for_each_set_bit(id, &supported_inputs, 32) {
		input = komeda_pipeline_get_component(pipe, id);
		if (!input) {
			c->supported_inputs &= ~(BIT(id));
			DRM_WARN("Can not find input(ID-%d) for component: %s.\n",
				 id, c->name);
			continue;
		}

		input->supported_outputs |= BIT(c->id);
	}
}

static struct komeda_layer *
komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
				   struct komeda_layer *left)
{
	int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
	int i;

	for (i = index + 1; i < pipe->n_layers; i++)
		if (left->layer_type == pipe->layers[i]->layer_type)
			return pipe->layers[i];
	return NULL;
}

static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
{
	struct komeda_component *c;
	struct komeda_layer *layer;
	int i, id;
	unsigned long avail_comps = pipe->avail_comps;

	for_each_set_bit(id, &avail_comps, 32) {
		c = komeda_pipeline_get_component(pipe, id);
		komeda_component_verify_inputs(c);
	}
	/* calculate right layer for the layer split */
	for (i = 0; i < pipe->n_layers; i++) {
		layer = pipe->layers[i];

		layer->right = komeda_get_layer_split_right_layer(pipe, layer);
	}

	if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) {
		pipe->dual_link = false;
		DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n",
			 pipe->id);
	}
}

/* if pipeline_A accept another pipeline_B's component as input, treat
 * pipeline_B as slave of pipeline_A.
 */
struct komeda_pipeline *
komeda_pipeline_get_slave(struct komeda_pipeline *master)
{
	struct komeda_component *slave;

	slave = komeda_component_pickup_input(&master->compiz->base,
					      KOMEDA_PIPELINE_COMPIZS);

	return slave ? slave->pipeline : NULL;
}

int komeda_assemble_pipelines(struct komeda_dev *mdev)
{
	struct komeda_pipeline *pipe;
	int i;

	for (i = 0; i < mdev->n_pipelines; i++) {
		pipe = mdev->pipelines[i];

		komeda_pipeline_assemble(pipe);
	}

	return 0;
}

void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
				   struct seq_file *sf)
{
	struct komeda_component *c;
	u32 id;
	unsigned long avail_comps;

	seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);

	if (pipe->funcs && pipe->funcs->dump_register)
		pipe->funcs->dump_register(pipe, sf);

	avail_comps = pipe->avail_comps;
	for_each_set_bit(id, &avail_comps, 32) {
		c = komeda_pipeline_get_component(pipe, id);

		seq_printf(sf, "\n------%s------\n", c->name);
		if (c->funcs->dump_register)
			c->funcs->dump_register(c, sf);
	}
}
