// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
 * Author: Eric Gao <eric.gao@rock-chips.com>
 */

#include <common.h>
#include <clk.h>
#include <display.h>
#include <dm.h>
#include <log.h>
#include <panel.h>
#include <regmap.h>
#include "rk_mipi.h"
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <dm/uclass-internal.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <asm/arch-rockchip/clock.h>
#include <asm/arch-rockchip/cru.h>
#include <asm/arch-rockchip/grf_rk3399.h>
#include <asm/arch-rockchip/hardware.h>
#include <asm/arch-rockchip/rockchip_mipi_dsi.h>

/* Select mipi dsi source, big or little vop */
static int rk_mipi_dsi_source_select(struct udevice *dev)
{
	struct rk_mipi_priv *priv = dev_get_priv(dev);
	struct rk3399_grf_regs *grf = priv->grf;
	struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev);

	/* Select the video source */
	switch (disp_uc_plat->source_id) {
	case VOP_B:
		rk_clrsetreg(&grf->soc_con20, GRF_DSI0_VOP_SEL_MASK,
			     GRF_DSI0_VOP_SEL_B << GRF_DSI0_VOP_SEL_SHIFT);
		break;
	case VOP_L:
		rk_clrsetreg(&grf->soc_con20, GRF_DSI0_VOP_SEL_MASK,
			     GRF_DSI0_VOP_SEL_L << GRF_DSI0_VOP_SEL_SHIFT);
		break;
	default:
		debug("%s: Invalid VOP id\n", __func__);
		return -EINVAL;
	}

	return 0;
}

/* Setup mipi dphy working mode */
static void rk_mipi_dphy_mode_set(struct udevice *dev)
{
	struct rk_mipi_priv *priv = dev_get_priv(dev);
	struct rk3399_grf_regs *grf = priv->grf;
	int val;

	/* Set Controller as TX mode */
	val = GRF_DPHY_TX0_RXMODE_DIS << GRF_DPHY_TX0_RXMODE_SHIFT;
	rk_clrsetreg(&grf->soc_con22, GRF_DPHY_TX0_RXMODE_MASK, val);

	/* Exit tx stop mode */
	val |= GRF_DPHY_TX0_TXSTOPMODE_DIS << GRF_DPHY_TX0_TXSTOPMODE_SHIFT;
	rk_clrsetreg(&grf->soc_con22, GRF_DPHY_TX0_TXSTOPMODE_MASK, val);

	/* Disable turnequest */
	val |= GRF_DPHY_TX0_TURNREQUEST_DIS << GRF_DPHY_TX0_TURNREQUEST_SHIFT;
	rk_clrsetreg(&grf->soc_con22, GRF_DPHY_TX0_TURNREQUEST_MASK, val);
}

/*
 * This function is called by rk_display_init() using rk_mipi_dsi_enable() and
 * rk_mipi_phy_enable() to initialize mipi controller and dphy. If success,
 * enable backlight.
 */
static int rk_display_enable(struct udevice *dev, int panel_bpp,
			  const struct display_timing *timing)
{
	int ret;
	struct rk_mipi_priv *priv = dev_get_priv(dev);

	/* Fill the mipi controller parameter */
	priv->ref_clk = 24 * MHz;
	priv->sys_clk = priv->ref_clk;
	priv->pix_clk = timing->pixelclock.typ;
	priv->phy_clk = priv->pix_clk * 6;
	priv->txbyte_clk = priv->phy_clk / 8;
	priv->txesc_clk = 20 * MHz;

	/* Select vop port, big or little */
	rk_mipi_dsi_source_select(dev);

	/* Set mipi dphy work mode */
	rk_mipi_dphy_mode_set(dev);

	/* Config  and enable mipi dsi according to timing */
	ret = rk_mipi_dsi_enable(dev, timing);
	if (ret) {
		debug("%s: rk_mipi_dsi_enable() failed (err=%d)\n",
		      __func__, ret);
		return ret;
	}

	/* Config and enable mipi phy */
	ret = rk_mipi_phy_enable(dev);
	if (ret) {
		debug("%s: rk_mipi_phy_enable() failed (err=%d)\n",
		      __func__, ret);
		return ret;
	}

	/* Enable backlight */
	ret = panel_enable_backlight(priv->panel);
	if (ret) {
		debug("%s: panel_enable_backlight() failed (err=%d)\n",
		      __func__, ret);
		return ret;
	}

	return 0;
}

static int rk_mipi_ofdata_to_platdata(struct udevice *dev)
{
	struct rk_mipi_priv *priv = dev_get_priv(dev);

	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
	if (IS_ERR_OR_NULL(priv->grf)) {
		debug("%s: Get syscon grf failed (ret=%p)\n",
		      __func__, priv->grf);
		return  -ENXIO;
	}
	priv->regs = dev_read_addr(dev);
	if (priv->regs == FDT_ADDR_T_NONE) {
		debug("%s: Get MIPI dsi address failed\n", __func__);
		return  -ENXIO;
	}

	return 0;
}

/*
 * Probe function: check panel existence and readingit's timing. Then config
 * mipi dsi controller and enable it according to the timing parameter.
 */
static int rk_mipi_probe(struct udevice *dev)
{
	int ret;
	struct rk_mipi_priv *priv = dev_get_priv(dev);

	ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel",
					   &priv->panel);
	if (ret) {
		debug("%s: Can not find panel (err=%d)\n", __func__, ret);
		return ret;
	}

	return 0;
}

static const struct dm_display_ops rk_mipi_dsi_ops = {
	.read_timing = rk_mipi_read_timing,
	.enable = rk_display_enable,
};

static const struct udevice_id rk_mipi_dsi_ids[] = {
	{ .compatible = "rockchip,rk3399_mipi_dsi" },
	{ }
};

U_BOOT_DRIVER(rk_mipi_dsi) = {
	.name	= "rk_mipi_dsi",
	.id	= UCLASS_DISPLAY,
	.of_match = rk_mipi_dsi_ids,
	.ofdata_to_platdata = rk_mipi_ofdata_to_platdata,
	.probe	= rk_mipi_probe,
	.ops	= &rk_mipi_dsi_ops,
	.priv_auto_alloc_size   = sizeof(struct rk_mipi_priv),
};
