/*
 * Copyright (C) STMicroelectronics SA 2014
 * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
 *          Fabien Dessenne <fabien.dessenne@st.com>
 *          Vincent Abriou <vincent.abriou@st.com>
 *          for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>

#include <drm/drmP.h>

#include "sti_vtg.h"

#define VTG_TYPE_MASTER         0
#define VTG_TYPE_SLAVE_BY_EXT0  1

/* registers offset */
#define VTG_MODE            0x0000
#define VTG_CLKLN           0x0008
#define VTG_HLFLN           0x000C
#define VTG_DRST_AUTOC      0x0010
#define VTG_VID_TFO         0x0040
#define VTG_VID_TFS         0x0044
#define VTG_VID_BFO         0x0048
#define VTG_VID_BFS         0x004C

#define VTG_HOST_ITS        0x0078
#define VTG_HOST_ITS_BCLR   0x007C
#define VTG_HOST_ITM_BCLR   0x0088
#define VTG_HOST_ITM_BSET   0x008C

#define VTG_H_HD_1          0x00C0
#define VTG_TOP_V_VD_1      0x00C4
#define VTG_BOT_V_VD_1      0x00C8
#define VTG_TOP_V_HD_1      0x00CC
#define VTG_BOT_V_HD_1      0x00D0

#define VTG_H_HD_2          0x00E0
#define VTG_TOP_V_VD_2      0x00E4
#define VTG_BOT_V_VD_2      0x00E8
#define VTG_TOP_V_HD_2      0x00EC
#define VTG_BOT_V_HD_2      0x00F0

#define VTG_H_HD_3          0x0100
#define VTG_TOP_V_VD_3      0x0104
#define VTG_BOT_V_VD_3      0x0108
#define VTG_TOP_V_HD_3      0x010C
#define VTG_BOT_V_HD_3      0x0110

#define VTG_H_HD_4          0x0120
#define VTG_TOP_V_VD_4      0x0124
#define VTG_BOT_V_VD_4      0x0128
#define VTG_TOP_V_HD_4      0x012c
#define VTG_BOT_V_HD_4      0x0130

#define VTG_IRQ_BOTTOM      BIT(0)
#define VTG_IRQ_TOP         BIT(1)
#define VTG_IRQ_MASK        (VTG_IRQ_TOP | VTG_IRQ_BOTTOM)

/* Delay introduced by the HDMI in nb of pixel */
#define HDMI_DELAY          (5)

/* delay introduced by the Arbitrary Waveform Generator in nb of pixels */
#define AWG_DELAY_HD        (-9)
#define AWG_DELAY_ED        (-8)
#define AWG_DELAY_SD        (-7)

LIST_HEAD(vtg_lookup);

/**
 * STI VTG structure
 *
 * @dev: pointer to device driver
 * @data: data associated to the device
 * @irq: VTG irq
 * @type: VTG type (main or aux)
 * @notifier_list: notifier callback
 * @crtc_id: the crtc id for vblank event
 * @slave: slave vtg
 * @link: List node to link the structure in lookup list
 */
struct sti_vtg {
	struct device *dev;
	struct device_node *np;
	void __iomem *regs;
	int irq;
	u32 irq_status;
	struct raw_notifier_head notifier_list;
	int crtc_id;
	struct sti_vtg *slave;
	struct list_head link;
};

static void vtg_register(struct sti_vtg *vtg)
{
	list_add_tail(&vtg->link, &vtg_lookup);
}

struct sti_vtg *of_vtg_find(struct device_node *np)
{
	struct sti_vtg *vtg;

	list_for_each_entry(vtg, &vtg_lookup, link) {
		if (vtg->np == np)
			return vtg;
	}
	return NULL;
}
EXPORT_SYMBOL(of_vtg_find);

static void vtg_reset(struct sti_vtg *vtg)
{
	/* reset slave and then master */
	if (vtg->slave)
		vtg_reset(vtg->slave);

	writel(1, vtg->regs + VTG_DRST_AUTOC);
}

static void vtg_set_output_window(void __iomem *regs,
				  const struct drm_display_mode *mode)
{
	u32 video_top_field_start;
	u32 video_top_field_stop;
	u32 video_bottom_field_start;
	u32 video_bottom_field_stop;
	u32 xstart = sti_vtg_get_pixel_number(*mode, 0);
	u32 ystart = sti_vtg_get_line_number(*mode, 0);
	u32 xstop = sti_vtg_get_pixel_number(*mode, mode->hdisplay - 1);
	u32 ystop = sti_vtg_get_line_number(*mode, mode->vdisplay - 1);

	/* Set output window to fit the display mode selected */
	video_top_field_start = (ystart << 16) | xstart;
	video_top_field_stop = (ystop << 16) | xstop;

	/* Only progressive supported for now */
	video_bottom_field_start = video_top_field_start;
	video_bottom_field_stop = video_top_field_stop;

	writel(video_top_field_start, regs + VTG_VID_TFO);
	writel(video_top_field_stop, regs + VTG_VID_TFS);
	writel(video_bottom_field_start, regs + VTG_VID_BFO);
	writel(video_bottom_field_stop, regs + VTG_VID_BFS);
}

static void vtg_set_mode(struct sti_vtg *vtg,
			 int type, const struct drm_display_mode *mode)
{
	u32 tmp;

	if (vtg->slave)
		vtg_set_mode(vtg->slave, VTG_TYPE_SLAVE_BY_EXT0, mode);

	/* Set the number of clock cycles per line */
	writel(mode->htotal, vtg->regs + VTG_CLKLN);

	/* Set Half Line Per Field (only progressive supported for now) */
	writel(mode->vtotal * 2, vtg->regs + VTG_HLFLN);

	/* Program output window */
	vtg_set_output_window(vtg->regs, mode);

	/* prepare VTG set 1 for HDMI */
	tmp = (mode->hsync_end - mode->hsync_start + HDMI_DELAY) << 16;
	tmp |= HDMI_DELAY;
	writel(tmp, vtg->regs + VTG_H_HD_1);

	tmp = (mode->vsync_end - mode->vsync_start + 1) << 16;
	tmp |= 1;
	writel(tmp, vtg->regs + VTG_TOP_V_VD_1);
	writel(tmp, vtg->regs + VTG_BOT_V_VD_1);

	tmp = HDMI_DELAY << 16;
	tmp |= HDMI_DELAY;
	writel(tmp, vtg->regs + VTG_TOP_V_HD_1);
	writel(tmp, vtg->regs + VTG_BOT_V_HD_1);

	/* prepare VTG set 2 for for HD DCS */
	tmp = (mode->hsync_end - mode->hsync_start) << 16;
	writel(tmp, vtg->regs + VTG_H_HD_2);

	tmp = (mode->vsync_end - mode->vsync_start + 1) << 16;
	tmp |= 1;
	writel(tmp, vtg->regs + VTG_TOP_V_VD_2);
	writel(tmp, vtg->regs + VTG_BOT_V_VD_2);
	writel(0, vtg->regs + VTG_TOP_V_HD_2);
	writel(0, vtg->regs + VTG_BOT_V_HD_2);

	/* prepare VTG set 3 for HD Analog in HD mode */
	tmp = (mode->hsync_end - mode->hsync_start + AWG_DELAY_HD) << 16;
	tmp |= mode->htotal + AWG_DELAY_HD;
	writel(tmp, vtg->regs + VTG_H_HD_3);

	tmp = (mode->vsync_end - mode->vsync_start) << 16;
	tmp |= mode->vtotal;
	writel(tmp, vtg->regs + VTG_TOP_V_VD_3);
	writel(tmp, vtg->regs + VTG_BOT_V_VD_3);

	tmp = (mode->htotal + AWG_DELAY_HD) << 16;
	tmp |= mode->htotal + AWG_DELAY_HD;
	writel(tmp, vtg->regs + VTG_TOP_V_HD_3);
	writel(tmp, vtg->regs + VTG_BOT_V_HD_3);

	/* Prepare VTG set 4 for DVO */
	tmp = (mode->hsync_end - mode->hsync_start) << 16;
	writel(tmp, vtg->regs + VTG_H_HD_4);

	tmp = (mode->vsync_end - mode->vsync_start + 1) << 16;
	tmp |= 1;
	writel(tmp, vtg->regs + VTG_TOP_V_VD_4);
	writel(tmp, vtg->regs + VTG_BOT_V_VD_4);
	writel(0, vtg->regs + VTG_TOP_V_HD_4);
	writel(0, vtg->regs + VTG_BOT_V_HD_4);

	/* mode */
	writel(type, vtg->regs + VTG_MODE);
}

static void vtg_enable_irq(struct sti_vtg *vtg)
{
	/* clear interrupt status and mask */
	writel(0xFFFF, vtg->regs + VTG_HOST_ITS_BCLR);
	writel(0xFFFF, vtg->regs + VTG_HOST_ITM_BCLR);
	writel(VTG_IRQ_MASK, vtg->regs + VTG_HOST_ITM_BSET);
}

void sti_vtg_set_config(struct sti_vtg *vtg,
		const struct drm_display_mode *mode)
{
	/* write configuration */
	vtg_set_mode(vtg, VTG_TYPE_MASTER, mode);

	vtg_reset(vtg);

	/* enable irq for the vtg vblank synchro */
	if (vtg->slave)
		vtg_enable_irq(vtg->slave);
	else
		vtg_enable_irq(vtg);
}
EXPORT_SYMBOL(sti_vtg_set_config);

/**
 * sti_vtg_get_line_number
 *
 * @mode: display mode to be used
 * @y:    line
 *
 * Return the line number according to the display mode taking
 * into account the Sync and Back Porch information.
 * Video frame line numbers start at 1, y starts at 0.
 * In interlaced modes the start line is the field line number of the odd
 * field, but y is still defined as a progressive frame.
 */
u32 sti_vtg_get_line_number(struct drm_display_mode mode, int y)
{
	u32 start_line = mode.vtotal - mode.vsync_start + 1;

	if (mode.flags & DRM_MODE_FLAG_INTERLACE)
		start_line *= 2;

	return start_line + y;
}
EXPORT_SYMBOL(sti_vtg_get_line_number);

/**
 * sti_vtg_get_pixel_number
 *
 * @mode: display mode to be used
 * @x:    row
 *
 * Return the pixel number according to the display mode taking
 * into account the Sync and Back Porch information.
 * Pixels are counted from 0.
 */
u32 sti_vtg_get_pixel_number(struct drm_display_mode mode, int x)
{
	return mode.htotal - mode.hsync_start + x;
}
EXPORT_SYMBOL(sti_vtg_get_pixel_number);

int sti_vtg_register_client(struct sti_vtg *vtg,
		struct notifier_block *nb, int crtc_id)
{
	if (vtg->slave)
		return sti_vtg_register_client(vtg->slave, nb, crtc_id);

	vtg->crtc_id = crtc_id;
	return raw_notifier_chain_register(&vtg->notifier_list, nb);
}
EXPORT_SYMBOL(sti_vtg_register_client);

int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb)
{
	if (vtg->slave)
		return sti_vtg_unregister_client(vtg->slave, nb);

	return raw_notifier_chain_unregister(&vtg->notifier_list, nb);
}
EXPORT_SYMBOL(sti_vtg_unregister_client);

static irqreturn_t vtg_irq_thread(int irq, void *arg)
{
	struct sti_vtg *vtg = arg;
	u32 event;

	event = (vtg->irq_status & VTG_IRQ_TOP) ?
		VTG_TOP_FIELD_EVENT : VTG_BOTTOM_FIELD_EVENT;

	raw_notifier_call_chain(&vtg->notifier_list, event, &vtg->crtc_id);

	return IRQ_HANDLED;
}

static irqreturn_t vtg_irq(int irq, void *arg)
{
	struct sti_vtg *vtg = arg;

	vtg->irq_status = readl(vtg->regs + VTG_HOST_ITS);

	writel(vtg->irq_status, vtg->regs + VTG_HOST_ITS_BCLR);

	/* force sync bus write */
	readl(vtg->regs + VTG_HOST_ITS);

	return IRQ_WAKE_THREAD;
}

static int vtg_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np;
	struct sti_vtg *vtg;
	struct resource *res;
	int ret;

	vtg = devm_kzalloc(dev, sizeof(*vtg), GFP_KERNEL);
	if (!vtg)
		return -ENOMEM;

	vtg->dev = dev;
	vtg->np = pdev->dev.of_node;

	/* Get Memory ressources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		DRM_ERROR("Get memory resource failed\n");
		return -ENOMEM;
	}
	vtg->regs = devm_ioremap_nocache(dev, res->start, resource_size(res));

	np = of_parse_phandle(pdev->dev.of_node, "st,slave", 0);
	if (np) {
		vtg->slave = of_vtg_find(np);

		if (!vtg->slave)
			return -EPROBE_DEFER;
	} else {
		vtg->irq = platform_get_irq(pdev, 0);
		if (IS_ERR_VALUE(vtg->irq)) {
			DRM_ERROR("Failed to get VTG interrupt\n");
			return vtg->irq;
		}

		RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list);

		ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq,
				vtg_irq_thread, IRQF_ONESHOT,
				dev_name(dev), vtg);
		if (IS_ERR_VALUE(ret)) {
			DRM_ERROR("Failed to register VTG interrupt\n");
			return ret;
		}
	}

	vtg_register(vtg);
	platform_set_drvdata(pdev, vtg);

	DRM_INFO("%s %s\n", __func__, dev_name(vtg->dev));

	return 0;
}

static int vtg_remove(struct platform_device *pdev)
{
	return 0;
}

static const struct of_device_id vtg_of_match[] = {
	{ .compatible = "st,vtg", },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, vtg_of_match);

struct platform_driver sti_vtg_driver = {
	.driver = {
		.name = "sti-vtg",
		.owner = THIS_MODULE,
		.of_match_table = vtg_of_match,
	},
	.probe	= vtg_probe,
	.remove = vtg_remove,
};

module_platform_driver(sti_vtg_driver);

MODULE_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
MODULE_LICENSE("GPL");
