/*
 * 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_drv.h"
#include "sti_vtg.h"

#define VTG_MODE_MASTER         0
#define VTG_MODE_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 DVO in nb of pixel */
#define DVO_DELAY           (7)

/* 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)

static LIST_HEAD(vtg_lookup);

/*
 * STI VTG register offset structure
 *
 *@h_hd:     stores the VTG_H_HD_x     register offset
 *@top_v_vd: stores the VTG_TOP_V_VD_x register offset
 *@bot_v_vd: stores the VTG_BOT_V_VD_x register offset
 *@top_v_hd: stores the VTG_TOP_V_HD_x register offset
 *@bot_v_hd: stores the VTG_BOT_V_HD_x register offset
 */
struct sti_vtg_regs_offs {
	u32 h_hd;
	u32 top_v_vd;
	u32 bot_v_vd;
	u32 top_v_hd;
	u32 bot_v_hd;
};

#define VTG_MAX_SYNC_OUTPUT 4
static const struct sti_vtg_regs_offs vtg_regs_offs[VTG_MAX_SYNC_OUTPUT] = {
	{ VTG_H_HD_1,
	  VTG_TOP_V_VD_1, VTG_BOT_V_VD_1, VTG_TOP_V_HD_1, VTG_BOT_V_HD_1 },
	{ VTG_H_HD_2,
	  VTG_TOP_V_VD_2, VTG_BOT_V_VD_2, VTG_TOP_V_HD_2, VTG_BOT_V_HD_2 },
	{ VTG_H_HD_3,
	  VTG_TOP_V_VD_3, VTG_BOT_V_VD_3, VTG_TOP_V_HD_3, VTG_BOT_V_HD_3 },
	{ VTG_H_HD_4,
	  VTG_TOP_V_VD_4, VTG_BOT_V_VD_4, VTG_TOP_V_HD_4, VTG_BOT_V_HD_4 }
};

/*
 * STI VTG synchronisation parameters structure
 *
 *@hsync: sample number falling and rising edge
 *@vsync_line_top: vertical top field line number falling and rising edge
 *@vsync_line_bot: vertical bottom field line number falling and rising edge
 *@vsync_off_top: vertical top field sample number rising and falling edge
 *@vsync_off_bot: vertical bottom field sample number rising and falling edge
 */
struct sti_vtg_sync_params {
	u32 hsync;
	u32 vsync_line_top;
	u32 vsync_line_bot;
	u32 vsync_off_top;
	u32 vsync_off_bot;
};

/**
 * STI VTG structure
 *
 * @dev: pointer to device driver
 * @np: device node
 * @regs: register mapping
 * @sync_params: synchronisation parameters used to generate timings
 * @irq: VTG irq
 * @irq_status: store the IRQ status value
 * @notifier_list: notifier callback
 * @crtc: the CRTC 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;
	struct sti_vtg_sync_params sync_params[VTG_MAX_SYNC_OUTPUT];
	int irq;
	u32 irq_status;
	struct raw_notifier_head notifier_list;
	struct drm_crtc *crtc;
	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;
}

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_hsync_vsync_pos(struct sti_vtg_sync_params *sync,
				    int delay,
				    const struct drm_display_mode *mode)
{
	long clocksperline, start, stop;
	u32 risesync_top, fallsync_top;
	u32 risesync_offs_top, fallsync_offs_top;

	clocksperline = mode->htotal;

	/* Get the hsync position */
	start = 0;
	stop = mode->hsync_end - mode->hsync_start;

	start += delay;
	stop  += delay;

	if (start < 0)
		start += clocksperline;
	else if (start >= clocksperline)
		start -= clocksperline;

	if (stop < 0)
		stop += clocksperline;
	else if (stop >= clocksperline)
		stop -= clocksperline;

	sync->hsync = (stop << 16) | start;

	/* Get the vsync position */
	if (delay >= 0) {
		risesync_top = 1;
		fallsync_top = risesync_top;
		fallsync_top += mode->vsync_end - mode->vsync_start;

		fallsync_offs_top = (u32)delay;
		risesync_offs_top = (u32)delay;
	} else {
		risesync_top = mode->vtotal;
		fallsync_top = mode->vsync_end - mode->vsync_start;

		fallsync_offs_top = clocksperline + delay;
		risesync_offs_top = clocksperline + delay;
	}

	sync->vsync_line_top = (fallsync_top << 16) | risesync_top;
	sync->vsync_off_top = (fallsync_offs_top << 16) | risesync_offs_top;

	/* Only progressive supported for now */
	sync->vsync_line_bot = sync->vsync_line_top;
	sync->vsync_off_bot = sync->vsync_off_top;
}

static void vtg_set_mode(struct sti_vtg *vtg,
			 int type,
			 struct sti_vtg_sync_params *sync,
			 const struct drm_display_mode *mode)
{
	unsigned int i;

	if (vtg->slave)
		vtg_set_mode(vtg->slave, VTG_MODE_SLAVE_BY_EXT0,
			     vtg->sync_params, 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);

	/* Set hsync and vsync position for HDMI */
	vtg_set_hsync_vsync_pos(&sync[VTG_SYNC_ID_HDMI - 1], HDMI_DELAY, mode);

	/* Set hsync and vsync position for HD DCS */
	vtg_set_hsync_vsync_pos(&sync[VTG_SYNC_ID_HDDCS - 1], 0, mode);

	/* Set hsync and vsync position for HDF */
	vtg_set_hsync_vsync_pos(&sync[VTG_SYNC_ID_HDF - 1], AWG_DELAY_HD, mode);

	/* Set hsync and vsync position for DVO */
	vtg_set_hsync_vsync_pos(&sync[VTG_SYNC_ID_DVO - 1], DVO_DELAY, mode);

	/* Progam the syncs outputs */
	for (i = 0; i < VTG_MAX_SYNC_OUTPUT ; i++) {
		writel(sync[i].hsync,
		       vtg->regs + vtg_regs_offs[i].h_hd);
		writel(sync[i].vsync_line_top,
		       vtg->regs + vtg_regs_offs[i].top_v_vd);
		writel(sync[i].vsync_line_bot,
		       vtg->regs + vtg_regs_offs[i].bot_v_vd);
		writel(sync[i].vsync_off_top,
		       vtg->regs + vtg_regs_offs[i].top_v_hd);
		writel(sync[i].vsync_off_bot,
		       vtg->regs + vtg_regs_offs[i].bot_v_hd);
	}

	/* 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_MODE_MASTER, vtg->sync_params, mode);

	vtg_reset(vtg);

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

/**
 * 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;
}

/**
 * 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;
}

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

	vtg->crtc = crtc;
	return raw_notifier_chain_register(&vtg->notifier_list, nb);
}

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);
}

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);

	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));
	if (!vtg->regs) {
		DRM_ERROR("failed to remap I/O memory\n");
		return -ENOMEM;
	}

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

		if (!vtg->slave)
			return -EPROBE_DEFER;
	} else {
		vtg->irq = platform_get_irq(pdev, 0);
		if (vtg->irq < 0) {
			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 (ret < 0) {
			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_AUTHOR("Benjamin Gaignard <benjamin.gaignard@st.com>");
MODULE_DESCRIPTION("STMicroelectronics SoC DRM driver");
MODULE_LICENSE("GPL");
