// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * linux/drivers/video/mmp/common.c
 * This driver is a common framework for Marvell Display Controller
 *
 * Copyright (C) 2012 Marvell Technology Group Ltd.
 * Authors: Zhou Zhu <zzhu3@marvell.com>
 */

#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
#include <linux/module.h>
#include <video/mmp_disp.h>

static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
		int overlay_id)
{
	if (path && overlay_id < path->overlay_num)
		return &path->overlays[overlay_id];
	return NULL;
}

static int path_check_status(struct mmp_path *path)
{
	int i;
	for (i = 0; i < path->overlay_num; i++)
		if (path->overlays[i].status)
			return 1;

	return 0;
}

/*
 * Get modelist write pointer of modelist.
 * It also returns modelist number
 * this function fetches modelist from phy/panel:
 *   for HDMI/parallel or dsi to hdmi cases, get from phy
 *   or get from panel
 */
static int path_get_modelist(struct mmp_path *path,
		struct mmp_mode **modelist)
{
	BUG_ON(!path || !modelist);

	if (path->panel && path->panel->get_modelist)
		return path->panel->get_modelist(path->panel, modelist);

	return 0;
}

/*
 * panel list is used to pair panel/path when path/panel registered
 * path list is used for both buffer driver and platdriver
 * plat driver do path register/unregister
 * panel driver do panel register/unregister
 * buffer driver get registered path
 */
static LIST_HEAD(panel_list);
static LIST_HEAD(path_list);
static DEFINE_MUTEX(disp_lock);

/*
 * mmp_register_panel - register panel to panel_list and connect to path
 * @p: panel to be registered
 *
 * this function provides interface for panel drivers to register panel
 * to panel_list and connect to path which matchs panel->plat_path_name.
 * no error returns when no matching path is found as path register after
 * panel register is permitted.
 */
void mmp_register_panel(struct mmp_panel *panel)
{
	struct mmp_path *path;

	mutex_lock(&disp_lock);

	/* add */
	list_add_tail(&panel->node, &panel_list);

	/* try to register to path */
	list_for_each_entry(path, &path_list, node) {
		if (!strcmp(panel->plat_path_name, path->name)) {
			dev_info(panel->dev, "connect to path %s\n",
				path->name);
			path->panel = panel;
			break;
		}
	}

	mutex_unlock(&disp_lock);
}
EXPORT_SYMBOL_GPL(mmp_register_panel);

/*
 * mmp_unregister_panel - unregister panel from panel_list and disconnect
 * @p: panel to be unregistered
 *
 * this function provides interface for panel drivers to unregister panel
 * from panel_list and disconnect from path.
 */
void mmp_unregister_panel(struct mmp_panel *panel)
{
	struct mmp_path *path;

	mutex_lock(&disp_lock);
	list_del(&panel->node);

	list_for_each_entry(path, &path_list, node) {
		if (path->panel && path->panel == panel) {
			dev_info(panel->dev, "disconnect from path %s\n",
				path->name);
			path->panel = NULL;
			break;
		}
	}
	mutex_unlock(&disp_lock);
}
EXPORT_SYMBOL_GPL(mmp_unregister_panel);

/*
 * mmp_get_path - get path by name
 * @p: path name
 *
 * this function checks path name in path_list and return matching path
 * return NULL if no matching path
 */
struct mmp_path *mmp_get_path(const char *name)
{
	struct mmp_path *path;
	int found = 0;

	mutex_lock(&disp_lock);
	list_for_each_entry(path, &path_list, node) {
		if (!strcmp(name, path->name)) {
			found = 1;
			break;
		}
	}
	mutex_unlock(&disp_lock);

	return found ? path : NULL;
}
EXPORT_SYMBOL_GPL(mmp_get_path);

/*
 * mmp_register_path - init and register path by path_info
 * @p: path info provided by display controller
 *
 * this function init by path info and register path to path_list
 * this function also try to connect path with panel by name
 */
struct mmp_path *mmp_register_path(struct mmp_path_info *info)
{
	int i;
	struct mmp_path *path = NULL;
	struct mmp_panel *panel;

	path = kzalloc(struct_size(path, overlays, info->overlay_num),
		       GFP_KERNEL);
	if (!path)
		return NULL;

	/* path set */
	mutex_init(&path->access_ok);
	path->dev = info->dev;
	path->id = info->id;
	path->name = info->name;
	path->output_type = info->output_type;
	path->overlay_num = info->overlay_num;
	path->plat_data = info->plat_data;
	path->ops.set_mode = info->set_mode;

	mutex_lock(&disp_lock);
	/* get panel */
	list_for_each_entry(panel, &panel_list, node) {
		if (!strcmp(info->name, panel->plat_path_name)) {
			dev_info(path->dev, "get panel %s\n", panel->name);
			path->panel = panel;
			break;
		}
	}

	dev_info(path->dev, "register %s, overlay_num %d\n",
			path->name, path->overlay_num);

	/* default op set: if already set by driver, never cover it */
	if (!path->ops.check_status)
		path->ops.check_status = path_check_status;
	if (!path->ops.get_overlay)
		path->ops.get_overlay = path_get_overlay;
	if (!path->ops.get_modelist)
		path->ops.get_modelist = path_get_modelist;

	/* step3: init overlays */
	for (i = 0; i < path->overlay_num; i++) {
		path->overlays[i].path = path;
		path->overlays[i].id = i;
		mutex_init(&path->overlays[i].access_ok);
		path->overlays[i].ops = info->overlay_ops;
	}

	/* add to pathlist */
	list_add_tail(&path->node, &path_list);

	mutex_unlock(&disp_lock);
	return path;
}
EXPORT_SYMBOL_GPL(mmp_register_path);

/*
 * mmp_unregister_path - unregister and destroy path
 * @p: path to be destroyed.
 *
 * this function registers path and destroys it.
 */
void mmp_unregister_path(struct mmp_path *path)
{
	int i;

	if (!path)
		return;

	mutex_lock(&disp_lock);
	/* del from pathlist */
	list_del(&path->node);

	/* deinit overlays */
	for (i = 0; i < path->overlay_num; i++)
		mutex_destroy(&path->overlays[i].access_ok);

	mutex_destroy(&path->access_ok);

	kfree(path);
	mutex_unlock(&disp_lock);
}
EXPORT_SYMBOL_GPL(mmp_unregister_path);

MODULE_AUTHOR("Zhou Zhu <zzhu3@marvell.com>");
MODULE_DESCRIPTION("Marvell MMP display framework");
MODULE_LICENSE("GPL");
