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

/* 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
 * @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 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)
{
	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;

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

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

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