// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2018 BayLibre, SAS
 * Author: Jorge Ramirez-Ortiz <jramirez@baylibre.com>
 */

#include <common.h>
#include <display.h>
#include <dm.h>
#include <edid.h>
#include <log.h>
#include <asm/io.h>
#include <dw_hdmi.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <linux/bitops.h>
#include <linux/printk.h>
#include <power/regulator.h>
#include <clk.h>
#include <linux/delay.h>
#include <reset.h>
#include <media_bus_format.h>
#include "meson_dw_hdmi.h"
#include "meson_vpu.h"

/* TOP Block Communication Channel */
#define HDMITX_TOP_ADDR_REG	0x0
#define HDMITX_TOP_DATA_REG	0x4
#define HDMITX_TOP_CTRL_REG	0x8
#define HDMITX_TOP_G12A_OFFSET	0x8000

/* Controller Communication Channel */
#define HDMITX_DWC_ADDR_REG	0x10
#define HDMITX_DWC_DATA_REG	0x14
#define HDMITX_DWC_CTRL_REG	0x18

/* HHI Registers */
#define HHI_MEM_PD_REG0		0x100 /* 0x40 */
#define HHI_HDMI_CLK_CNTL	0x1cc /* 0x73 */
#define HHI_HDMI_PHY_CNTL0	0x3a0 /* 0xe8 */
#define HHI_HDMI_PHY_CNTL1	0x3a4 /* 0xe9 */
#define HHI_HDMI_PHY_CNTL2	0x3a8 /* 0xea */
#define HHI_HDMI_PHY_CNTL3	0x3ac /* 0xeb */
#define HHI_HDMI_PHY_CNTL4	0x3b0 /* 0xec */
#define HHI_HDMI_PHY_CNTL5	0x3b4 /* 0xed */

struct meson_dw_hdmi {
	struct udevice *dev;
	struct dw_hdmi hdmi;
	void __iomem *hhi_base;
};

enum hdmi_compatible {
	HDMI_COMPATIBLE_GXBB = 0,
	HDMI_COMPATIBLE_GXL = 1,
	HDMI_COMPATIBLE_GXM = 2,
	HDMI_COMPATIBLE_G12A = 3,
};

static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv,
					    enum hdmi_compatible family)
{
	enum hdmi_compatible compat = dev_get_driver_data(priv->dev);

	return compat == family;
}

static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr)
{
	struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi,
						  hdmi);
	unsigned int data;

	if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A))
		return readl(hdmi->ioaddr +
			     HDMITX_TOP_G12A_OFFSET + (addr << 2));

	/* ADDR must be written twice */
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG);
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG);

	/* Read needs a second DATA read */
	data = readl(hdmi->ioaddr + HDMITX_TOP_DATA_REG);
	data = readl(hdmi->ioaddr + HDMITX_TOP_DATA_REG);

	return data;
}

static inline void dw_hdmi_top_write(struct dw_hdmi *hdmi,
				     unsigned int addr, unsigned int data)
{
	struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi,
						  hdmi);

	if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) {
		writel(data, hdmi->ioaddr +
		       HDMITX_TOP_G12A_OFFSET + (addr << 2));
		return;
	}

	/* ADDR must be written twice */
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG);
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG);

	/* Write needs single DATA write */
	writel(data, hdmi->ioaddr + HDMITX_TOP_DATA_REG);
}

static inline void dw_hdmi_top_write_bits(struct dw_hdmi *hdmi,
					  unsigned int addr,
					  unsigned int mask,
					  unsigned int val)
{
	unsigned int data = dw_hdmi_top_read(hdmi, addr);

	data &= ~mask;
	data |= val;
	dw_hdmi_top_write(hdmi, addr, data);
}

static u8 dw_hdmi_dwc_read(struct dw_hdmi *hdmi, int addr)
{
	unsigned int data;

	/* ADDR must be written twice */
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_DWC_ADDR_REG);
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_DWC_ADDR_REG);

	/* Read needs a second DATA read */
	data = readl(hdmi->ioaddr + HDMITX_DWC_DATA_REG);
	data = readl(hdmi->ioaddr + HDMITX_DWC_DATA_REG);

	return data;
}

static inline void dw_hdmi_dwc_write(struct dw_hdmi *hdmi, u8 data, int addr)
{
	/* ADDR must be written twice */
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_DWC_ADDR_REG);
	writel(addr & 0xffff, hdmi->ioaddr + HDMITX_DWC_ADDR_REG);

	/* Write needs single DATA write */
	writel(data, hdmi->ioaddr + HDMITX_DWC_DATA_REG);
}

static inline void dw_hdmi_dwc_write_bits(struct dw_hdmi *hdmi,
					  unsigned int addr,
					  unsigned int mask,
					  unsigned int val)
{
	u8 data = dw_hdmi_dwc_read(hdmi, addr);

	data &= ~mask;
	data |= val;

	dw_hdmi_dwc_write(hdmi, data, addr);
}

static inline void dw_hdmi_hhi_write(struct meson_dw_hdmi *priv,
				     unsigned int addr, unsigned int data)
{
	hhi_write(addr, data);
}

__attribute__((unused))
static unsigned int dw_hdmi_hhi_read(struct meson_dw_hdmi *priv,
				     unsigned int addr)
{
	return hhi_read(addr);
}

static inline void dw_hdmi_hhi_update_bits(struct meson_dw_hdmi *priv,
					   unsigned int addr,
					   unsigned int mask,
					   unsigned int val)
{
	hhi_update_bits(addr, mask, val);
}

static int meson_dw_hdmi_read_edid(struct udevice *dev, u8 *buf, int buf_size)
{
#if defined DEBUG
	struct display_timing timing;
	int panel_bits_per_colour;
#endif
	struct meson_dw_hdmi *priv = dev_get_priv(dev);
	int ret;

	ret = dw_hdmi_read_edid(&priv->hdmi, buf, buf_size);

#if defined DEBUG
	if (!ret)
		return ret;

	edid_print_info((struct edid1_info *)buf);
	edid_get_timing(buf, ret, &timing, &panel_bits_per_colour);
	debug("Display timing:\n");
	debug(" hactive %04d, hfrontp %04d, hbackp %04d hsync %04d\n"
	      " vactive %04d, vfrontp %04d, vbackp %04d vsync %04d\n",
	       timing.hactive.typ, timing.hfront_porch.typ,
	       timing.hback_porch.typ, timing.hsync_len.typ,
	       timing.vactive.typ, timing.vfront_porch.typ,
	       timing.vback_porch.typ, timing.vsync_len.typ);
	debug(" flags: ");
	if (timing.flags & DISPLAY_FLAGS_INTERLACED)
		debug("interlaced ");
	if (timing.flags & DISPLAY_FLAGS_DOUBLESCAN)
		debug("doublescan ");
	if (timing.flags & DISPLAY_FLAGS_DOUBLECLK)
		debug("doubleclk ");
	if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW)
		debug("hsync_low ");
	if (timing.flags & DISPLAY_FLAGS_HSYNC_HIGH)
		debug("hsync_high ");
	if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW)
		debug("vsync_low ");
	if (timing.flags & DISPLAY_FLAGS_VSYNC_HIGH)
		debug("vsync_high ");
	debug("\n");
#endif

	return ret;
}

static inline void meson_dw_hdmi_phy_reset(struct meson_dw_hdmi *priv)
{
	/* Enable and software reset */
	dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, 0xf, 0xf);

	mdelay(2);

	/* Enable and unreset */
	dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, 0xf, 0xe);

	mdelay(2);
}

static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv,
					 uint pixel_clock)
{
	pixel_clock = pixel_clock / 1000;

	if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXL) ||
	    meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM)) {
		if (pixel_clock >= 371250) {
			/* 5.94Gbps, 3.7125Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x333d3282);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2136315b);
		} else if (pixel_clock >= 297000) {
			/* 2.97Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33303382);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2036315b);
		} else if (pixel_clock >= 148500) {
			/* 1.485Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33303362);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2016315b);
		} else {
			/* 742.5Mbps, and below */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33604142);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x0016315b);
		}
	} else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXBB)) {
		if (pixel_clock >= 371250) {
			/* 5.94Gbps, 3.7125Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33353245);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2100115b);
		} else if (pixel_clock >= 297000) {
			/* 2.97Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33634283);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0xb000115b);
		} else {
			/* 1.485Gbps, and below */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33632122);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2000115b);
		}
	} else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) {
		if (pixel_clock >= 371250) {
			/* 5.94Gbps, 3.7125Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x37eb65c4);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
			hhi_write(HHI_HDMI_PHY_CNTL5, 0x0000080b);
		} else if (pixel_clock >= 297000) {
			/* 2.97Gbps */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb6262);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
			hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003);
		} else {
			/* 1.485Gbps, and below */
			hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb4242);
			hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b);
			hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003);
		}
	}
}

static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock)
{
	struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi,
						  hdmi);
	/* Enable clocks */
	dw_hdmi_hhi_update_bits(priv, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);

	/* Bring HDMITX MEM output of power down */
	dw_hdmi_hhi_update_bits(priv, HHI_MEM_PD_REG0, 0xff << 8, 0);

	/* Bring out of reset */
	dw_hdmi_top_write(hdmi, HDMITX_TOP_SW_RESET,  0);

	/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
	dw_hdmi_top_write_bits(hdmi, HDMITX_TOP_CLK_CNTL, 0x3, 0x3);
	dw_hdmi_top_write_bits(hdmi, HDMITX_TOP_CLK_CNTL, 0x3 << 4, 0x3 << 4);

	/* Enable normal output to PHY */
	dw_hdmi_top_write(hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));

	/* TMDS pattern setup (TOFIX pattern for 4k2k scrambling) */
	dw_hdmi_top_write(hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, 0x001f001f);
	dw_hdmi_top_write(hdmi, HDMITX_TOP_TMDS_CLK_PTTN_23, 0x001f001f);

	/* Load TMDS pattern */
	dw_hdmi_top_write(hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x1);
	mdelay(20);
	dw_hdmi_top_write(hdmi, HDMITX_TOP_TMDS_CLK_PTTN_CNTL, 0x2);

	/* Setup PHY parameters */
	meson_dw_hdmi_phy_setup_mode(priv, pixel_clock);

	/* Setup PHY */
	dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1,
				0xffff << 16, 0x0390 << 16);

	/* BIT_INVERT */
	if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXL) ||
	    meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM) ||
	    meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A))
		dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, BIT(17), 0);
	else
		dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1,
					BIT(17), BIT(17));

	/* Disable clock, fifo, fifo_wr */
	dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, 0xf, 0);

	mdelay(100);

	/* Reset PHY 3 times in a row */
	meson_dw_hdmi_phy_reset(priv);
	meson_dw_hdmi_phy_reset(priv);
	meson_dw_hdmi_phy_reset(priv);

	return 0;
}

static int meson_dw_hdmi_enable(struct udevice *dev, int panel_bpp,
				const struct display_timing *edid)
{
	struct meson_dw_hdmi *priv = dev_get_priv(dev);

	/* will back into meson_dw_hdmi_phy_init */
	return dw_hdmi_enable(&priv->hdmi, edid);
}

static int meson_dw_hdmi_wait_hpd(struct dw_hdmi *hdmi)
{
	int i;

	/* Poll 1 second for HPD signal */
	for (i = 0; i < 10; ++i) {
		if (dw_hdmi_top_read(hdmi, HDMITX_TOP_STAT0))
			return 0;

		mdelay(100);
	}

	return -ETIMEDOUT;
}

static int meson_dw_hdmi_probe(struct udevice *dev)
{
	struct meson_dw_hdmi *priv = dev_get_priv(dev);
	struct reset_ctl_bulk resets;
	struct clk_bulk clocks;
#if CONFIG_IS_ENABLED(DM_REGULATOR)
	struct udevice *supply;
#endif
	int ret;

	priv->dev = dev;

	priv->hdmi.ioaddr = (ulong)dev_remap_addr_index(dev, 0);
	if (!priv->hdmi.ioaddr)
		return -EINVAL;

	priv->hhi_base = dev_remap_addr_index(dev, 1);
	if (!priv->hhi_base)
		return -EINVAL;

	priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24;
	priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24;
	priv->hdmi.phy_set = meson_dw_hdmi_phy_init;
	if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A))
		priv->hdmi.reg_io_width = 1;
	else {
		priv->hdmi.write_reg = dw_hdmi_dwc_write;
		priv->hdmi.read_reg = dw_hdmi_dwc_read;
	}
	priv->hdmi.i2c_clk_high = 0x67;
	priv->hdmi.i2c_clk_low = 0x78;

#if CONFIG_IS_ENABLED(DM_REGULATOR)
	ret = device_get_supply_regulator(dev, "hdmi-supply", &supply);
	if (ret && ret != -ENOENT) {
		pr_err("Failed to get HDMI regulator\n");
		return ret;
	}

	if (!ret) {
		ret = regulator_set_enable(supply, true);
		if (ret)
			return ret;
	}
#endif

	uclass_get_device_by_phandle(UCLASS_I2C, dev, "ddc-i2c-bus",
				     &priv->hdmi.ddc_bus);

	ret = reset_get_bulk(dev, &resets);
	if (ret)
		return ret;

	ret = clk_get_bulk(dev, &clocks);
	if (ret)
		return ret;

	ret = clk_enable_bulk(&clocks);
	if (ret)
		return ret;

	/* Enable clocks */
	dw_hdmi_hhi_update_bits(priv, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);

	/* Bring HDMITX MEM output of power down */
	dw_hdmi_hhi_update_bits(priv, HHI_MEM_PD_REG0, 0xff << 8, 0);

	/* Reset HDMITX APB & TX & PHY: cycle needed for EDID */
	ret = reset_deassert_bulk(&resets);
	if (ret)
		return ret;

	ret = reset_assert_bulk(&resets);
	if (ret)
		return ret;

	ret = reset_deassert_bulk(&resets);
	if (ret)
		return ret;

	if (!meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) {
		/* Enable APB3 fail on error */
		writel_bits(BIT(15), BIT(15),
			    priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG);
		writel_bits(BIT(15), BIT(15),
			    priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG);
	}

	/* Bring out of reset */
	dw_hdmi_top_write(&priv->hdmi, HDMITX_TOP_SW_RESET,  0);
	mdelay(20);
	dw_hdmi_top_write(&priv->hdmi, HDMITX_TOP_CLK_CNTL, 0xff);

	dw_hdmi_init(&priv->hdmi);
	dw_hdmi_phy_init(&priv->hdmi);

	/* wait for connector */
	ret = meson_dw_hdmi_wait_hpd(&priv->hdmi);
	if (ret)
		debug("hdmi can not get hpd signal\n");

	return ret;
}

static bool meson_dw_hdmi_mode_valid(struct udevice *dev,
				     const struct display_timing *timing)
{
	return meson_venc_hdmi_supported_mode(timing);
}

static const struct dm_display_ops meson_dw_hdmi_ops = {
	.read_edid = meson_dw_hdmi_read_edid,
	.enable = meson_dw_hdmi_enable,
	.mode_valid = meson_dw_hdmi_mode_valid,
};

static const struct udevice_id meson_dw_hdmi_ids[] = {
	{ .compatible = "amlogic,meson-gxbb-dw-hdmi",
		.data = HDMI_COMPATIBLE_GXBB },
	{ .compatible = "amlogic,meson-gxl-dw-hdmi",
		.data = HDMI_COMPATIBLE_GXL },
	{ .compatible = "amlogic,meson-gxm-dw-hdmi",
		.data = HDMI_COMPATIBLE_GXM },
	{ .compatible = "amlogic,meson-g12a-dw-hdmi",
		.data = HDMI_COMPATIBLE_G12A },
	{ }
};

U_BOOT_DRIVER(meson_dw_hdmi) = {
	.name = "meson_dw_hdmi",
	.id = UCLASS_DISPLAY,
	.of_match = meson_dw_hdmi_ids,
	.ops = &meson_dw_hdmi_ops,
	.probe = meson_dw_hdmi_probe,
	.priv_auto	= sizeof(struct meson_dw_hdmi),
};
