/*
 * Copyright 2016 Rockchip Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <clk.h>
#include <display.h>
#include <dm.h>
#include <edid.h>
#include <panel.h>
#include <regmap.h>
#include <syscon.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/lvds_rk3288.h>
#include <asm/arch/grf_rk3288.h>
#include <dt-bindings/clock/rk3288-cru.h>
#include <dt-bindings/video/rk3288.h>

DECLARE_GLOBAL_DATA_PTR;

/**
 * struct rk_lvds_priv - private rockchip lvds display driver info
 *
 * @reg: LVDS register address
 * @grf: GRF register
 * @panel: Panel device that is used in driver
 *
 * @output: Output mode, decided single or double channel,
 *		LVDS or LVTLL
 * @format: Data format that RGB data will packing as
 */
struct rk_lvds_priv {
	void __iomem *regs;
	struct rk3288_grf *grf;
	struct udevice *panel;

	int output;
	int format;
};

static inline void lvds_writel(struct rk_lvds_priv *lvds, u32 offset, u32 val)
{
	writel(val, lvds->regs + offset);

	writel(val, lvds->regs + offset + 0x100);
}

int rk_lvds_enable(struct udevice *dev, int panel_bpp,
		   const struct display_timing *edid)
{
	struct rk_lvds_priv *priv = dev_get_priv(dev);
	struct display_plat *uc_plat = dev_get_uclass_platdata(dev);
	int ret = 0;
	unsigned int val = 0;

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

	/* Select the video source */
	if (uc_plat->source_id)
		val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT |
		    (RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16);
	else
		val = RK3288_LVDS_SOC_CON6_SEL_VOP_LIT << 16;
	rk_setreg(&priv->grf->soc_con6, val);

	/* Select data transfer format */
	val = priv->format;
	if (priv->output == LVDS_OUTPUT_DUAL)
		val |= LVDS_DUAL | LVDS_CH0_EN | LVDS_CH1_EN;
	else if (priv->output == LVDS_OUTPUT_SINGLE)
		val |= LVDS_CH0_EN;
	else if (priv->output == LVDS_OUTPUT_RGB)
		val |= LVDS_TTL_EN | LVDS_CH0_EN | LVDS_CH1_EN;
	val |= (0xffff << 16);
	rk_setreg(&priv->grf->soc_con7, val);

	/* Enable LVDS PHY */
	if (priv->output == LVDS_OUTPUT_RGB) {
		lvds_writel(priv, RK3288_LVDS_CH0_REG0,
			    RK3288_LVDS_CH0_REG0_TTL_EN |
			    RK3288_LVDS_CH0_REG0_LANECK_EN |
			    RK3288_LVDS_CH0_REG0_LANE4_EN |
			    RK3288_LVDS_CH0_REG0_LANE3_EN |
			    RK3288_LVDS_CH0_REG0_LANE2_EN |
			    RK3288_LVDS_CH0_REG0_LANE1_EN |
			    RK3288_LVDS_CH0_REG0_LANE0_EN);
		lvds_writel(priv, RK3288_LVDS_CH0_REG2,
			    RK3288_LVDS_PLL_FBDIV_REG2(0x46));

		lvds_writel(priv, RK3288_LVDS_CH0_REG3,
			    RK3288_LVDS_PLL_FBDIV_REG3(0x46));
		lvds_writel(priv, RK3288_LVDS_CH0_REG4,
			    RK3288_LVDS_CH0_REG4_LANECK_TTL_MODE |
			    RK3288_LVDS_CH0_REG4_LANE4_TTL_MODE |
			    RK3288_LVDS_CH0_REG4_LANE3_TTL_MODE |
			    RK3288_LVDS_CH0_REG4_LANE2_TTL_MODE |
			    RK3288_LVDS_CH0_REG4_LANE1_TTL_MODE |
			    RK3288_LVDS_CH0_REG4_LANE0_TTL_MODE);
		lvds_writel(priv, RK3288_LVDS_CH0_REG5,
			    RK3288_LVDS_CH0_REG5_LANECK_TTL_DATA |
			    RK3288_LVDS_CH0_REG5_LANE4_TTL_DATA |
			    RK3288_LVDS_CH0_REG5_LANE3_TTL_DATA |
			    RK3288_LVDS_CH0_REG5_LANE2_TTL_DATA |
			    RK3288_LVDS_CH0_REG5_LANE1_TTL_DATA |
			    RK3288_LVDS_CH0_REG5_LANE0_TTL_DATA);
		lvds_writel(priv, RK3288_LVDS_CH0_REGD,
			    RK3288_LVDS_PLL_PREDIV_REGD(0x0a));
		lvds_writel(priv, RK3288_LVDS_CH0_REG20,
			    RK3288_LVDS_CH0_REG20_LSB);
	} else {
		lvds_writel(priv, RK3288_LVDS_CH0_REG0,
			    RK3288_LVDS_CH0_REG0_LVDS_EN |
			    RK3288_LVDS_CH0_REG0_LANECK_EN |
			    RK3288_LVDS_CH0_REG0_LANE4_EN |
			    RK3288_LVDS_CH0_REG0_LANE3_EN |
			    RK3288_LVDS_CH0_REG0_LANE2_EN |
			    RK3288_LVDS_CH0_REG0_LANE1_EN |
			    RK3288_LVDS_CH0_REG0_LANE0_EN);
		lvds_writel(priv, RK3288_LVDS_CH0_REG1,
			    RK3288_LVDS_CH0_REG1_LANECK_BIAS |
			    RK3288_LVDS_CH0_REG1_LANE4_BIAS |
			    RK3288_LVDS_CH0_REG1_LANE3_BIAS |
			    RK3288_LVDS_CH0_REG1_LANE2_BIAS |
			    RK3288_LVDS_CH0_REG1_LANE1_BIAS |
			    RK3288_LVDS_CH0_REG1_LANE0_BIAS);
		lvds_writel(priv, RK3288_LVDS_CH0_REG2,
			    RK3288_LVDS_CH0_REG2_RESERVE_ON |
			    RK3288_LVDS_CH0_REG2_LANECK_LVDS_MODE |
			    RK3288_LVDS_CH0_REG2_LANE4_LVDS_MODE |
			    RK3288_LVDS_CH0_REG2_LANE3_LVDS_MODE |
			    RK3288_LVDS_CH0_REG2_LANE2_LVDS_MODE |
			    RK3288_LVDS_CH0_REG2_LANE1_LVDS_MODE |
			    RK3288_LVDS_CH0_REG2_LANE0_LVDS_MODE |
			    RK3288_LVDS_PLL_FBDIV_REG2(0x46));
		lvds_writel(priv, RK3288_LVDS_CH0_REG3,
			    RK3288_LVDS_PLL_FBDIV_REG3(0x46));
		lvds_writel(priv, RK3288_LVDS_CH0_REG4, 0x00);
		lvds_writel(priv, RK3288_LVDS_CH0_REG5, 0x00);
		lvds_writel(priv, RK3288_LVDS_CH0_REGD,
			    RK3288_LVDS_PLL_PREDIV_REGD(0x0a));
		lvds_writel(priv, RK3288_LVDS_CH0_REG20,
			    RK3288_LVDS_CH0_REG20_LSB);
	}

	/* Power on */
	writel(RK3288_LVDS_CFG_REGC_PLL_ENABLE,
	       priv->regs + RK3288_LVDS_CFG_REGC);

	writel(RK3288_LVDS_CFG_REG21_TX_ENABLE,
	       priv->regs + RK3288_LVDS_CFG_REG21);

	return 0;
}

int rk_lvds_read_timing(struct udevice *dev, struct display_timing *timing)
{
	if (fdtdec_decode_display_timing
	    (gd->fdt_blob, dev->of_offset, 0, timing)) {
		debug("%s: Failed to decode display timing\n", __func__);
		return -EINVAL;
	}

	return 0;
}

static int rk_lvds_ofdata_to_platdata(struct udevice *dev)
{
	struct rk_lvds_priv *priv = dev_get_priv(dev);
	const void *blob = gd->fdt_blob;
	int node = dev->of_offset;
	int ret;
	priv->regs = (void *)dev_get_addr(dev);
	priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);

	ret = fdtdec_get_int(blob, node, "rockchip,output", -1);
	if (ret != -1) {
		priv->output = ret;
		debug("LVDS output : %d\n", ret);
	} else {
		/* default set it as output rgb */
		priv->output = LVDS_OUTPUT_RGB;
	}

	ret = fdtdec_get_int(blob, node, "rockchip,data-mapping", -1);
	if (ret != -1) {
		priv->format = ret;
		debug("LVDS data-mapping : %d\n", ret);
	} else {
		/* default set it as format jeida */
		priv->format = LVDS_FORMAT_JEIDA;
	}

	ret = fdtdec_get_int(blob, node, "rockchip,data-width", -1);
	if (ret != -1) {
		debug("LVDS data-width : %d\n", ret);
		if (ret == 24) {
			priv->format |= LVDS_24BIT;
		} else if (ret == 18) {
			priv->format |= LVDS_18BIT;
		} else {
			debug("rockchip-lvds unsupport data-width[%d]\n", ret);
			ret = -EINVAL;
			return ret;
		}
	} else {
		priv->format |= LVDS_24BIT;
	}

	return 0;
}

int rk_lvds_probe(struct udevice *dev)
{
	struct rk_lvds_priv *priv = dev_get_priv(dev);
	int ret;

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

	return 0;
}

static const struct dm_display_ops lvds_rockchip_ops = {
	.read_timing = rk_lvds_read_timing,
	.enable = rk_lvds_enable,
};

static const struct udevice_id rockchip_lvds_ids[] = {
	{.compatible = "rockchip,rk3288-lvds"},
	{}
};

U_BOOT_DRIVER(lvds_rockchip) = {
	.name	= "lvds_rockchip",
	.id	= UCLASS_DISPLAY,
	.of_match = rockchip_lvds_ids,
	.ops	= &lvds_rockchip_ops,
	.ofdata_to_platdata	= rk_lvds_ofdata_to_platdata,
	.probe	= rk_lvds_probe,
	.priv_auto_alloc_size	= sizeof(struct rk_lvds_priv),
};
