/*
 * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe@pengutronix.de>
 *
 * This is based on code from:
 * Author: Vitaly Wool <vital@embeddedalley.com>
 *
 * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include <common.h>
#include <init.h>
#include <driver.h>
#include <malloc.h>
#include <errno.h>
#include <xfuncs.h>
#include <asm/io.h>
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <mach/fb.h>

#define HW_LCDIF_CTRL 0x00
# define CTRL_SFTRST (1 << 31)
# define CTRL_CLKGATE (1 << 30)
# define CTRL_BYPASS_COUNT (1 << 19)
# define CTRL_VSYNC_MODE (1 << 18)
# define CTRL_DOTCLK_MODE (1 << 17)
# define CTRL_DATA_SELECT (1 << 16)
# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
# define CTRL_MASTER (1 << 5)
# define CTRL_DF16 (1 << 3)
# define CTRL_DF18 (1 << 2)
# define CTRL_DF24 (1 << 1)
# define CTRL_RUN (1 << 0)

#define HW_LCDIF_CTRL1 0x10
# define CTRL1_FIFO_CLEAR (1 << 21)
# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
# define CTRL1_RESET (1 << 0)

#ifdef CONFIG_ARCH_IMX28
# define HW_LCDIF_CTRL2 0x20
# define HW_LCDIF_TRANSFER_COUNT 0x30
#endif
#ifdef CONFIG_ARCH_IMX23
# define HW_LCDIF_TRANSFER_COUNT 0x20
#endif
# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
# define SET_HCOUNT(x) ((x) & 0xffff)

#ifdef CONFIG_ARCH_IMX28
# define HW_LCDIF_CUR_BUF 0x40
# define HW_LCDIF_NEXT_BUF 0x50
#endif
#ifdef CONFIG_ARCH_IMX23
# define HW_LCDIF_CUR_BUF 0x30
# define HW_LCDIF_NEXT_BUF 0x40
#endif

#define HW_LCDIF_TIMING 0x60
# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
# define SET_DATA_SETUP(x) ((x) & 0xff)

#define HW_LCDIF_VDCTRL0 0x70
# define VDCTRL0_ENABLE_PRESENT (1 << 28)
# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output@falling, capturing@rising edge */
# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
# define VDCTRL0_HALF_LINE (1 << 19)
# define VDCTRL0_HALF_LINE_MODE (1 << 18)
# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)

#define HW_LCDIF_VDCTRL1 0x80

#define HW_LCDIF_VDCTRL2 0x90
#ifdef CONFIG_ARCH_IMX28
# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
#endif
#ifdef CONFIG_ARCH_IMX23
# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0xff) << 24)
#endif
# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)

#define HW_LCDIF_VDCTRL3 0xa0
# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
# define VDCTRL3_VSYNC_ONLY (1 << 28)
# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)

#define HW_LCDIF_VDCTRL4 0xb0
#ifdef CONFIG_ARCH_IMX28
# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
#endif
# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)

#define HW_LCDIF_DVICTRL0 0xc0
#define HW_LCDIF_DVICTRL1 0xd0
#define HW_LCDIF_DVICTRL2 0xe0
#define HW_LCDIF_DVICTRL3 0xf0
#define HW_LCDIF_DVICTRL4 0x100

#ifdef CONFIG_ARCH_IMX28
# define HW_LCDIF_DATA 0x180
#endif
#ifdef CONFIG_ARCH_IMX23
# define HW_LCDIF_DATA 0x1b0
#endif

#ifdef CONFIG_ARCH_IMX28
# define HW_LCDIF_DEBUG0 0x1d0
#endif
#ifdef CONFIG_ARCH_IMX23
# define HW_LCDIF_DEBUG0 0x1f0
#endif
# define DEBUG_HSYNC (1 < 26)
# define DEBUG_VSYNC (1 < 25)

#define RED 0
#define GREEN 1
#define BLUE 2
#define TRANSP 3

struct imxfb_info {
	void __iomem *base;
	unsigned memory_size;
	struct fb_info info;
	struct device_d *hw_dev;
	struct imx_fb_platformdata *pdata;
};

/* the RGB565 true colour mode */
static const struct fb_bitfield def_rgb565[] = {
	[RED] = {
		.offset = 11,
		.length = 5,
	},
	[GREEN] = {
		.offset = 5,
		.length = 6,
	},
	[BLUE] = {
		.offset = 0,
		.length = 5,
	},
	[TRANSP] = {	/* no support for transparency */
		.length = 0,
	}
};

/* the RGB666 true colour mode */
static const struct fb_bitfield def_rgb666[] = {
	[RED] = {
		.offset = 16,
		.length = 6,
	},
	[GREEN] = {
		.offset = 8,
		.length = 6,
	},
	[BLUE] = {
		.offset = 0,
		.length = 6,
	},
	[TRANSP] = {	/* no support for transparency */
		.length = 0,
	}
};

/* the RGB888 true colour mode */
static const struct fb_bitfield def_rgb888[] = {
	[RED] = {
		.offset = 16,
		.length = 8,
	},
	[GREEN] = {
		.offset = 8,
		.length = 8,
	},
	[BLUE] = {
		.offset = 0,
		.length = 8,
	},
	[TRANSP] = {	/* no support for transparency */
		.length = 0,
	}
};

static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
{
	if (bpp == 24)
		bpp = 32;
	return (ppl * bpp) >> 3;
}

static void stmfb_enable_controller(struct fb_info *fb_info)
{
	struct imxfb_info *fbi = fb_info->priv;
	uint32_t reg, last_reg;
	unsigned loop, edges;

	/*
	 * Sometimes some data is still present in the FIFO. This leads into
	 * a correct but shifted picture. Clearing the FIFO helps
	 */
	writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_SET);

	/* if it was disabled, re-enable the mode again */
	reg = readl(fbi->base + HW_LCDIF_CTRL);
	reg |= CTRL_DOTCLK_MODE;
	writel(reg, fbi->base + HW_LCDIF_CTRL);

	/* enable the SYNC signals first, then the DMA engine */
	reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
	reg |= VDCTRL4_SYNC_SIGNALS_ON;
	writel(reg, fbi->base + HW_LCDIF_VDCTRL4);

	/*
	 * Give the attached LC display or monitor a chance to sync into
	 * our signals.
	 * Wait for at least 2 VSYNCs = four VSYNC edges
	 */
	edges = 4;

	while (edges != 0) {
		loop = 800;
		last_reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
		do {
			reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
			if (reg != last_reg)
				break;
			last_reg = reg;
			loop--;
		} while (loop != 0);
		edges--;
	}

	/* stop FIFO reset */
	writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_CLR);

	/* enable LCD using LCD_RESET signal*/
	if (fbi->pdata->flags & USE_LCD_RESET)
		writel(CTRL1_RESET,  fbi->base + HW_LCDIF_CTRL1 + BIT_SET);

	/* start the engine right now */
	writel(CTRL_RUN, fbi->base + HW_LCDIF_CTRL + BIT_SET);

	if (fbi->pdata->enable)
		fbi->pdata->enable(1);
}

static void stmfb_disable_controller(struct fb_info *fb_info)
{
	struct imxfb_info *fbi = fb_info->priv;
	unsigned loop;
	uint32_t reg;


	/* disable LCD using LCD_RESET signal*/
	if (fbi->pdata->flags & USE_LCD_RESET)
		writel(CTRL1_RESET,  fbi->base + HW_LCDIF_CTRL1 + BIT_CLR);

	if (fbi->pdata->enable)
		fbi->pdata->enable(0);

	/*
	 * Even if we disable the controller here, it will still continue
	 * until its FIFOs are running out of data
	 */
	reg = readl(fbi->base + HW_LCDIF_CTRL);
	reg &= ~CTRL_DOTCLK_MODE;
	writel(reg, fbi->base + HW_LCDIF_CTRL);

	loop = 1000;
	while (loop) {
		reg = readl(fbi->base + HW_LCDIF_CTRL);
		if (!(reg & CTRL_RUN))
			break;
		loop--;
	}

	reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
	reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
	writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
}

static int stmfb_activate_var(struct fb_info *fb_info)
{
	struct imxfb_info *fbi = fb_info->priv;
	struct imx_fb_platformdata *pdata = fbi->pdata;
	struct fb_videomode *mode = fb_info->mode;
	uint32_t reg;
	unsigned size;

	/*
	 * we need at least this amount of memory for the framebuffer
	 */
	size = calc_line_length(mode->xres, fb_info->bits_per_pixel) *
		mode->yres;

	if (pdata->fixed_screen) {
		if (pdata->fixed_screen_size < size)
			return -ENOMEM;
		fb_info->screen_base = pdata->fixed_screen;
		fbi->memory_size = pdata->fixed_screen_size;
	} else {
		fb_info->screen_base = xrealloc(fb_info->screen_base, size);
		fbi->memory_size = size;
	}

	/** @todo ensure HCLK is active at this point of time! */

	size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock) * 1000);
	if (size == 0) {
		dev_dbg(fbi->hw_dev, "Unable to set a valid pixel clock\n");
		return -EINVAL;
	}

	/*
	 * bring the controller out of reset and
	 * configure it into DOTCLOCK mode
	 */
	reg = CTRL_BYPASS_COUNT |	/* always in DOTCLOCK mode */
		CTRL_DOTCLK_MODE;
	writel(reg, fbi->base + HW_LCDIF_CTRL);

	/* master mode only */
	reg |= CTRL_MASTER;

	/*
	 * Configure videomode and interface mode
	 */
	reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
	switch (fb_info->bits_per_pixel) {
	case 8:
		reg |= SET_WORD_LENGTH(1);
		/** @todo refer manual page 2046 for 8 bpp modes */
		dev_dbg(fbi->hw_dev, "8 bpp mode not supported yet\n");
		break;
	case 16:
		pr_debug("Setting up an RGB565 mode\n");
		reg |= SET_WORD_LENGTH(0);
		reg &= ~CTRL_DF16; /* we assume RGB565 */
		writel(SET_BYTE_PACKAGING(0xf), fbi->base + HW_LCDIF_CTRL1);
		fb_info->red = def_rgb565[RED];
		fb_info->green = def_rgb565[GREEN];
		fb_info->blue = def_rgb565[BLUE];
		fb_info->transp =  def_rgb565[TRANSP];
		break;
	case 24:
	case 32:
		pr_debug("Setting up an RGB888/666 mode\n");
		reg |= SET_WORD_LENGTH(3);
		switch (pdata->ld_intf_width) {
		case STMLCDIF_8BIT:
			dev_dbg(fbi->hw_dev,
				"Unsupported LCD bus width mapping\n");
			break;
		case STMLCDIF_16BIT:
		case STMLCDIF_18BIT:
			/* 24 bit to 18 bit mapping
			 * which means: ignore the upper 2 bits in
			 * each colour component
			 */
			reg |= CTRL_DF24;
			fb_info->red = def_rgb666[RED];
			fb_info->green = def_rgb666[GREEN];
			fb_info->blue = def_rgb666[BLUE];
			fb_info->transp =  def_rgb666[TRANSP];
			break;
		case STMLCDIF_24BIT:
			/* real 24 bit */
			fb_info->red = def_rgb888[RED];
			fb_info->green = def_rgb888[GREEN];
			fb_info->blue = def_rgb888[BLUE];
			fb_info->transp =  def_rgb888[TRANSP];
			break;
		}
		/* do not use packed pixels = one pixel per word instead */
		writel(SET_BYTE_PACKAGING(0x7), fbi->base + HW_LCDIF_CTRL1);
		break;
	default:
		dev_dbg(fbi->hw_dev, "Unhandled colour depth of %u\n",
			fb_info->bits_per_pixel);
		return -EINVAL;
	}
	writel(reg, fbi->base + HW_LCDIF_CTRL);
	pr_debug("Setting up CTRL to %08X\n", reg);

	writel(SET_VCOUNT(mode->yres) |
		SET_HCOUNT(mode->xres), fbi->base + HW_LCDIF_TRANSFER_COUNT);

	reg = VDCTRL0_ENABLE_PRESENT |	/* always in DOTCLOCK mode */
		VDCTRL0_VSYNC_PERIOD_UNIT |
		VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
	if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
		reg |= VDCTRL0_HSYNC_POL;
	if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
		reg |= VDCTRL0_VSYNC_POL;
	if (mode->sync & FB_SYNC_DE_HIGH_ACT)
		reg |= VDCTRL0_ENABLE_POL;
	if (mode->sync & FB_SYNC_CLK_INVERT)
		reg |= VDCTRL0_DOTCLK_POL;

	reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
	writel(reg, fbi->base + HW_LCDIF_VDCTRL0);
	pr_debug("Setting up VDCTRL0 to %08X\n", reg);

	/* frame length in lines */
	writel(mode->upper_margin + mode->vsync_len + mode->lower_margin +
			mode->yres,
		fbi->base + HW_LCDIF_VDCTRL1);

	/* line length in units of clocks or pixels */
	writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
		SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len +
			mode->right_margin + mode->xres),
		fbi->base + HW_LCDIF_VDCTRL2);

	writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
		SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
		fbi->base + HW_LCDIF_VDCTRL3);

	writel(
#ifdef CONFIG_ARCH_IMX28
		SET_DOTCLK_DLY(pdata->dotclk_delay) |
#endif
		SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
		fbi->base + HW_LCDIF_VDCTRL4);

	writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_CUR_BUF);
	writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_NEXT_BUF);

	return 0;
}

static void stmfb_info(struct device_d *hw_dev)
{
	struct imx_fb_platformdata *pdata = hw_dev->platform_data;
	unsigned u;

	printf(" Supported video modes:\n");
	for (u = 0; u < pdata->mode_cnt; u++)
		printf("  - '%s': %u x %u\n", pdata->mode_list[u].name,
			pdata->mode_list[u].xres, pdata->mode_list[u].yres);
}

/*
 * There is only one video hardware instance available.
 * It makes no sense to dynamically allocate this data
 */
static struct fb_ops imxfb_ops = {
	.fb_activate_var = stmfb_activate_var,
	.fb_enable = stmfb_enable_controller,
	.fb_disable = stmfb_disable_controller,
};

static struct imxfb_info fbi = {
	.info = {
		.fbops = &imxfb_ops,
	},
};

static int stmfb_probe(struct device_d *hw_dev)
{
	struct imx_fb_platformdata *pdata = hw_dev->platform_data;
	int ret;

	/* just init */
	fbi.info.priv = &fbi;

	/* add runtime hardware info */
	fbi.hw_dev = hw_dev;
	fbi.base = (void *)hw_dev->map_base;
	fbi.pdata = pdata;

	/* add runtime video info */
	fbi.info.mode_list = pdata->mode_list;
	fbi.info.num_modes = pdata->mode_cnt;
	fbi.info.mode = &fbi.info.mode_list[0];
	fbi.info.xres = fbi.info.mode->xres;
	fbi.info.yres = fbi.info.mode->yres;
	if (pdata->bits_per_pixel)
		fbi.info.bits_per_pixel = pdata->bits_per_pixel;
	else
		fbi.info.bits_per_pixel = 16;

	ret = register_framebuffer(&fbi.info);
	if (ret != 0) {
		dev_err(hw_dev, "Failed to register framebuffer\n");
		return -EINVAL;
	}

	return 0;
}

static struct driver_d stmfb_driver = {
	.name	= "stmfb",
	.probe	= stmfb_probe,
	.info	= stmfb_info,
};

static int stmfb_init(void)
{
	return register_driver(&stmfb_driver);
}

device_initcall(stmfb_init);

/**
 * @file
 * @brief LCDIF driver for i.MX23 and i.MX28
 *
 * The LCDIF support four modes of operation
 * - MPU interface (to drive smart displays) -> not supported yet
 * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
 * - Dotclock interface (to drive LC displays with RGB data and sync signals)
 * - DVI (to drive ITU-R BT656)  -> not supported yet
 *
 * This driver depends on a correct setup of the pins used for this purpose
 * (platform specific).
 *
 * For the developer: Don't forget to set the data bus width to the display
 * in the imx_fb_platformdata structure. You will else end up with ugly colours.
 * If you fight against jitter you can vary the clock delay. This is a feature
 * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
 * the required value in the imx_fb_platformdata structure.
 */
