// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2012 Sascha Hauer, Pengutronix
 * Copyright 2019,2020,2022 NXP
 */

#include <linux/export.h>
#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>

#include <drm/drm_bridge.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>

#include "imx-ldb-helper.h"

bool ldb_channel_is_single_link(struct ldb_channel *ldb_ch)
{
	return ldb_ch->link_type == LDB_CH_SINGLE_LINK;
}
EXPORT_SYMBOL_GPL(ldb_channel_is_single_link);

bool ldb_channel_is_split_link(struct ldb_channel *ldb_ch)
{
	return ldb_ch->link_type == LDB_CH_DUAL_LINK_EVEN_ODD_PIXELS ||
	       ldb_ch->link_type == LDB_CH_DUAL_LINK_ODD_EVEN_PIXELS;
}
EXPORT_SYMBOL_GPL(ldb_channel_is_split_link);

int ldb_bridge_atomic_check_helper(struct drm_bridge *bridge,
				   struct drm_bridge_state *bridge_state,
				   struct drm_crtc_state *crtc_state,
				   struct drm_connector_state *conn_state)
{
	struct ldb_channel *ldb_ch = bridge->driver_private;

	ldb_ch->in_bus_format = bridge_state->input_bus_cfg.format;
	ldb_ch->out_bus_format = bridge_state->output_bus_cfg.format;

	return 0;
}
EXPORT_SYMBOL_GPL(ldb_bridge_atomic_check_helper);

void ldb_bridge_mode_set_helper(struct drm_bridge *bridge,
				const struct drm_display_mode *mode,
				const struct drm_display_mode *adjusted_mode)
{
	struct ldb_channel *ldb_ch = bridge->driver_private;
	struct ldb *ldb = ldb_ch->ldb;
	bool is_split = ldb_channel_is_split_link(ldb_ch);

	if (is_split)
		ldb->ldb_ctrl |= LDB_SPLIT_MODE_EN;

	switch (ldb_ch->out_bus_format) {
	case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
		break;
	case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
		if (ldb_ch->chno == 0 || is_split)
			ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24;
		if (ldb_ch->chno == 1 || is_split)
			ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24;
		break;
	case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
		if (ldb_ch->chno == 0 || is_split)
			ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
					 LDB_BIT_MAP_CH0_JEIDA;
		if (ldb_ch->chno == 1 || is_split)
			ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
					 LDB_BIT_MAP_CH1_JEIDA;
		break;
	}
}
EXPORT_SYMBOL_GPL(ldb_bridge_mode_set_helper);

void ldb_bridge_enable_helper(struct drm_bridge *bridge)
{
	struct ldb_channel *ldb_ch = bridge->driver_private;
	struct ldb *ldb = ldb_ch->ldb;

	/*
	 * Platform specific bridge drivers should set ldb_ctrl properly
	 * for the enablement, so just write the ctrl_reg here.
	 */
	regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ldb_ctrl);
}
EXPORT_SYMBOL_GPL(ldb_bridge_enable_helper);

void ldb_bridge_disable_helper(struct drm_bridge *bridge)
{
	struct ldb_channel *ldb_ch = bridge->driver_private;
	struct ldb *ldb = ldb_ch->ldb;
	bool is_split = ldb_channel_is_split_link(ldb_ch);

	if (ldb_ch->chno == 0 || is_split)
		ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
	if (ldb_ch->chno == 1 || is_split)
		ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK;

	regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ldb_ctrl);
}
EXPORT_SYMBOL_GPL(ldb_bridge_disable_helper);

int ldb_bridge_attach_helper(struct drm_bridge *bridge,
			     enum drm_bridge_attach_flags flags)
{
	struct ldb_channel *ldb_ch = bridge->driver_private;
	struct ldb *ldb = ldb_ch->ldb;

	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
		DRM_DEV_ERROR(ldb->dev,
			      "do not support creating a drm_connector\n");
		return -EINVAL;
	}

	if (!bridge->encoder) {
		DRM_DEV_ERROR(ldb->dev, "missing encoder\n");
		return -ENODEV;
	}

	return drm_bridge_attach(bridge->encoder,
				ldb_ch->next_bridge, bridge,
				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
}
EXPORT_SYMBOL_GPL(ldb_bridge_attach_helper);

int ldb_init_helper(struct ldb *ldb)
{
	struct device *dev = ldb->dev;
	struct device_node *np = dev->of_node;
	struct device_node *child;
	int ret;
	u32 i;

	ldb->regmap = syscon_node_to_regmap(np->parent);
	if (IS_ERR(ldb->regmap)) {
		ret = PTR_ERR(ldb->regmap);
		if (ret != -EPROBE_DEFER)
			DRM_DEV_ERROR(dev, "failed to get regmap: %d\n", ret);
		return ret;
	}

	for_each_available_child_of_node(np, child) {
		struct ldb_channel *ldb_ch;

		ret = of_property_read_u32(child, "reg", &i);
		if (ret || i > MAX_LDB_CHAN_NUM - 1) {
			ret = -EINVAL;
			DRM_DEV_ERROR(dev,
				      "invalid channel node address: %u\n", i);
			of_node_put(child);
			return ret;
		}

		ldb_ch = ldb->channel[i];
		ldb_ch->ldb = ldb;
		ldb_ch->chno = i;
		ldb_ch->is_available = true;
		ldb_ch->np = child;

		ldb->available_ch_cnt++;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(ldb_init_helper);

int ldb_find_next_bridge_helper(struct ldb *ldb)
{
	struct device *dev = ldb->dev;
	struct ldb_channel *ldb_ch;
	int ret, i;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		ldb_ch = ldb->channel[i];

		if (!ldb_ch->is_available)
			continue;

		ldb_ch->next_bridge = devm_drm_of_get_bridge(dev, ldb_ch->np,
							     1, 0);
		if (IS_ERR(ldb_ch->next_bridge)) {
			ret = PTR_ERR(ldb_ch->next_bridge);
			if (ret != -EPROBE_DEFER)
				DRM_DEV_ERROR(dev,
					      "failed to get next bridge: %d\n",
					      ret);
			return ret;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(ldb_find_next_bridge_helper);

void ldb_add_bridge_helper(struct ldb *ldb,
			   const struct drm_bridge_funcs *bridge_funcs)
{
	struct ldb_channel *ldb_ch;
	int i;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		ldb_ch = ldb->channel[i];

		if (!ldb_ch->is_available)
			continue;

		ldb_ch->bridge.driver_private = ldb_ch;
		ldb_ch->bridge.funcs = bridge_funcs;
		ldb_ch->bridge.of_node = ldb_ch->np;

		drm_bridge_add(&ldb_ch->bridge);
	}
}
EXPORT_SYMBOL_GPL(ldb_add_bridge_helper);

void ldb_remove_bridge_helper(struct ldb *ldb)
{
	struct ldb_channel *ldb_ch;
	int i;

	for (i = 0; i < MAX_LDB_CHAN_NUM; i++) {
		ldb_ch = ldb->channel[i];

		if (!ldb_ch->is_available)
			continue;

		drm_bridge_remove(&ldb_ch->bridge);
	}
}
EXPORT_SYMBOL_GPL(ldb_remove_bridge_helper);

MODULE_DESCRIPTION("i.MX8 LVDS Display Bridge(LDB)/Pixel Mapper bridge helper");
MODULE_AUTHOR("Liu Ying <victor.liu@nxp.com>");
MODULE_LICENSE("GPL");
