/*
 *  Freescale i.MX Frame Buffer device driver
 *
 *  Copyright (C) 2004 Sascha Hauer, Pengutronix
 *   Based on acornfb.c Copyright (C) Russell King.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive for
 * more details.
 *
 * Please direct your questions and comments on this driver to the following
 * email address:
 *
 *	linux-arm-kernel@lists.arm.linux.org.uk
 */

#include <common.h>
#include <fb.h>
#include <asm/io.h>
#include <mach/imxfb.h>
#include <driver.h>
#include <malloc.h>
#include <errno.h>
#include <init.h>
#include <mach/imx-regs.h>
#include <asm-generic/div64.h>
#include <mach/clock.h>

#define LCDC_SSA	0x00

#define LCDC_SIZE	0x04
#define SIZE_XMAX(x)	((((x) >> 4) & 0x3f) << 20)

#ifdef CONFIG_ARCH_IMX1
#define SIZE_YMAX(y)	((y) & 0x1ff)
#else
#define SIZE_YMAX(y)	((y) & 0x3ff)
#endif

#define LCDC_VPW	0x08
#define VPW_VPW(x)	((x) & 0x3ff)

#define LCDC_CPOS	0x0C
#define CPOS_CC1	(1<<31)
#define CPOS_CC0	(1<<30)
#define CPOS_OP		(1<<28)
#define CPOS_CXP(x)	(((x) & 3ff) << 16)

#ifdef CONFIG_ARCH_IMX1
#define CPOS_CYP(y)	((y) & 0x1ff)
#else
#define CPOS_CYP(y)	((y) & 0x3ff)
#endif

#define LCDC_LCWHB	0x10
#define LCWHB_BK_EN	(1<<31)
#define LCWHB_CW(w)	(((w) & 0x1f) << 24)
#define LCWHB_CH(h)	(((h) & 0x1f) << 16)
#define LCWHB_BD(x)	((x) & 0xff)

#define LCDC_LCHCC	0x14

#ifdef CONFIG_ARCH_IMX1
#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11)
#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5)
#define LCHCC_CUR_COL_B(b) ((b) & 0x1f)
#else
#define LCHCC_CUR_COL_R(r) (((r) & 0x3f) << 12)
#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 6)
#define LCHCC_CUR_COL_B(b) ((b) & 0x3f)
#endif

#define LCDC_PCR	0x18

#define LCDC_HCR	0x1C
#define HCR_H_WIDTH(x)	(((x) & 0x3f) << 26)
#define HCR_H_WAIT_1(x)	(((x) & 0xff) << 8)
#define HCR_H_WAIT_2(x)	((x) & 0xff)

#define LCDC_VCR	0x20
#define VCR_V_WIDTH(x)	(((x) & 0x3f) << 26)
#define VCR_V_WAIT_1(x)	(((x) & 0xff) << 8)
#define VCR_V_WAIT_2(x)	((x) & 0xff)

#define LCDC_POS	0x24
#define POS_POS(x)	((x) & 1f)

#define LCDC_LSCR1	0x28
/* bit fields in imxfb.h */

#define LCDC_PWMR	0x2C
/* bit fields in imxfb.h */

#define LCDC_DMACR	0x30
/* bit fields in imxfb.h */

#define LCDC_RMCR	0x34

#ifdef CONFIG_ARCH_IMX1
#define RMCR_LCDC_EN	(1<<1)
#else
#define RMCR_LCDC_EN	0
#endif

#define RMCR_SELF_REF	(1<<0)

#define LCDC_LCDICR	0x38
#define LCDICR_INT_SYN	(1<<2)
#define LCDICR_INT_CON	(1)

#define LCDC_LCDISR	0x40
#define LCDISR_UDR_ERR	(1<<3)
#define LCDISR_ERR_RES	(1<<2)
#define LCDISR_EOF	(1<<1)
#define LCDISR_BOF	(1<<0)

#define LCDC_LGWSAR	0x50
#define LCDC_LGWSR	0x54
#define LCDC_LGWVPWR	0x58
#define LCDC_LGWPOR	0x5c
#define LCDC_LGWPR	0x60
#define LCDC_LGWCR	0x64
#define LGWCR_GWAV(alpha)	(((alpha) & 0xff) << 24)
#define LGWCR_GWE	(1 << 22)

#define LCDC_LGWDCR	0x68

/*
 * These are the bitfields for each
 * display depth that we support.
 */
struct imxfb_rgb {
	struct fb_bitfield	red;
	struct fb_bitfield	green;
	struct fb_bitfield	blue;
	struct fb_bitfield	transp;
};

struct imxfb_info {
	void __iomem		*regs;

	u_int			pcr;
	u_int			pwmr;
	u_int			lscr1;
	u_int			dmacr;
	u_int			cmap_inverse:1,
				cmap_static:1,
				unused:30;

	struct imx_fb_videomode *mode;

	struct fb_info		info;
	struct device_d		*dev;

	void			(*enable)(int enable);

	struct fb_info		overlay;
};

#define IMX_NAME	"IMX"

/*
 * Minimum X and Y resolutions
 */
#define MIN_XRES	64
#define MIN_YRES	64

/* Actually this really is 18bit support, the lowest 2 bits of each colour
 * are unused in hardware. We claim to have 24bit support to make software
 * like X work, which does not support 18bit.
 */
static struct imxfb_rgb def_rgb_18 = {
	.red	= {.offset = 16, .length = 8,},
	.green	= {.offset = 8, .length = 8,},
	.blue	= {.offset = 0, .length = 8,},
	.transp = {.offset = 0, .length = 0,},
};

static struct imxfb_rgb def_rgb_16_tft = {
	.red	= {.offset = 11, .length = 5,},
	.green	= {.offset = 5, .length = 6,},
	.blue	= {.offset = 0, .length = 5,},
	.transp = {.offset = 0, .length = 0,},
};

static struct imxfb_rgb def_rgb_16_stn = {
	.red	= {.offset = 8, .length = 4,},
	.green	= {.offset = 4, .length = 4,},
	.blue	= {.offset = 0, .length = 4,},
	.transp = {.offset = 0, .length = 0,},
};

static struct imxfb_rgb def_rgb_8 = {
	.red	= {.offset = 0, .length = 8,},
	.green	= {.offset = 0, .length = 8,},
	.blue	= {.offset = 0, .length = 8,},
	.transp = {.offset = 0, .length = 0,},
};

static inline u_int chan_to_field(u_int chan, struct fb_bitfield *bf)
{
	chan &= 0xffff;
	chan >>= 16 - bf->length;
	return chan << bf->offset;
}


static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
		   u_int trans, struct fb_info *info)
{
	struct imxfb_info *fbi = info->priv;
	int ret = 1;
	u32 val;

	/*
	 * If inverse mode was selected, invert all the colours
	 * rather than the register number.  The register number
	 * is what you poke into the framebuffer to produce the
	 * colour you requested.
	 */
	if (fbi->cmap_inverse) {
		red   = 0xffff - red;
		green = 0xffff - green;
		blue  = 0xffff - blue;
	}

	/*
	 * If greyscale is true, then we convert the RGB value
	 * to greyscale no matter what visual we are using.
	 */
	if (info->grayscale)
		red = green = blue = (19595 * red + 38470 * green +
					7471 * blue) >> 16;

#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
	if (regno < 256) {
		val = (CNVT_TOHW(red, 4) << 8) |
		      (CNVT_TOHW(green,4) << 4) |
		      CNVT_TOHW(blue,  4);

		writel(val, fbi->regs + 0x800 + (regno << 2));
		ret = 0;
	}

	return ret;
}

static void imxfb_enable_controller(struct fb_info *info)
{
	struct imxfb_info *fbi = info->priv;

	writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR);
#ifdef CONFIG_ARCH_IMX21
	PCCR0 |= PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN;
#endif
#ifdef CONFIG_ARCH_IMX27
	PCCR0 |= PCCR0_LCDC_EN;
	PCCR1 |= PCCR1_HCLK_LCDC;
#endif
#ifdef CONFIG_ARCH_IMX25
	writel(readl(IMX_CCM_BASE + CCM_CGCR0) | (1 << 24) | (1 << 7),
		IMX_CCM_BASE + CCM_CGCR0);
	writel(readl(IMX_CCM_BASE + CCM_CGCR1) | (1 << 29),
		IMX_CCM_BASE + CCM_CGCR1);
#endif
	if (fbi->enable)
		fbi->enable(1);
}

static void imxfb_disable_controller(struct fb_info *info)
{
	struct imxfb_info *fbi = info->priv;

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

	writel(0, fbi->regs + LCDC_RMCR);
#ifdef CONFIG_ARCH_IMX21
	PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN);
#endif
#ifdef CONFIG_ARCH_IMX27
	PCCR0 &= ~PCCR0_LCDC_EN;
	PCCR1 &= ~PCCR1_HCLK_LCDC;
#endif
#ifdef CONFIG_ARCH_IMX25
	writel(readl(IMX_CCM_BASE + CCM_CGCR0) & ~((1 << 24) | (1 << 7)),
		IMX_CCM_BASE + CCM_CGCR0);
	writel(readl(IMX_CCM_BASE + CCM_CGCR1) & ~(1 << 29),
		IMX_CCM_BASE + CCM_CGCR1);
#endif
}

/*
 * imxfb_activate_var():
 *	Configures LCD Controller based on entries in var parameter.  Settings are
 *	only written to the controller if changes were made.
 */
static int imxfb_activate_var(struct fb_info *info)
{
	struct fb_videomode *mode = info->mode;
	struct imxfb_rgb *rgb;
	unsigned long lcd_clk;
	unsigned long long tmp;
	struct imxfb_info *fbi = info->priv;
	u32 pcr;

	/* physical screen start address	    */
	writel(VPW_VPW(mode->xres * info->bits_per_pixel / 8 / 4),
		fbi->regs + LCDC_VPW);

	writel(HCR_H_WIDTH(mode->hsync_len - 1) |
		HCR_H_WAIT_1(mode->right_margin - 1) |
		HCR_H_WAIT_2(mode->left_margin - 3),
		fbi->regs + LCDC_HCR);

	writel(VCR_V_WIDTH(mode->vsync_len) |
		VCR_V_WAIT_1(mode->lower_margin) |
		VCR_V_WAIT_2(mode->upper_margin),
		fbi->regs + LCDC_VCR);

	writel(SIZE_XMAX(info->xres) | SIZE_YMAX(info->yres),
			fbi->regs + LCDC_SIZE);

	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);
	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);
	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);
	writel((unsigned long)fbi->info.screen_base, fbi->regs + LCDC_SSA);

	/* panning offset 0 (0 pixel offset)        */
	writel(0x0, fbi->regs + LCDC_POS);

	/* disable hardware cursor */
	writel(readl(fbi->regs + LCDC_CPOS) & ~(CPOS_CC0 | CPOS_CC1),
		fbi->regs + LCDC_CPOS);

	lcd_clk = imx_get_lcdclk();

	tmp = mode->pixclock * (unsigned long long)lcd_clk;

	do_div(tmp, 1000000);

	if (do_div(tmp, 1000000) > 500000)
		tmp++;

	pcr = (unsigned int)tmp;
	if (--pcr > 0x3f) {
		pcr = 0x3f;
		printk(KERN_WARNING "Must limit pixel clock to %luHz\n",
				lcd_clk / pcr);
	}

	switch (info->bits_per_pixel) {
	case 32:
		pcr |= PCR_BPIX_18;
		rgb = &def_rgb_18;
		break;
	case 16:
	default:
#ifdef CONFIG_ARCH_IMX1
		pcr |= PCR_BPIX_12;
#else
		pcr |= PCR_BPIX_16;
#endif
		if (fbi->pcr & PCR_TFT)
			rgb = &def_rgb_16_tft;
		else
			rgb = &def_rgb_16_stn;
		break;
	case 8:
		pcr |= PCR_BPIX_8;
		rgb = &def_rgb_8;
		break;
	}

	writel(fbi->pcr | pcr, fbi->regs + LCDC_PCR);

	/*
	 * Copy the RGB parameters for this display
	 * from the machine specific parameters.
	 */
	info->red    = rgb->red;
	info->green  = rgb->green;
	info->blue   = rgb->blue;
	info->transp = rgb->transp;

	return 0;
}

static struct fb_ops imxfb_ops = {
	.fb_setcolreg	= imxfb_setcolreg,
	.fb_enable	= imxfb_enable_controller,
	.fb_disable	= imxfb_disable_controller,
};

#ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY
static void imxfb_overlay_enable_controller(struct fb_info *overlay)
{
	struct imxfb_info *fbi = overlay->priv;
	unsigned int tmp;

	tmp = readl(fbi->regs + LCDC_LGWCR);
	tmp |= LGWCR_GWE;
	writel(tmp , fbi->regs + LCDC_LGWCR);
}

static void imxfb_overlay_disable_controller(struct fb_info *overlay)
{
	struct imxfb_info *fbi = overlay->priv;
	unsigned int tmp;

	tmp = readl(fbi->regs + LCDC_LGWCR);
	tmp &= ~LGWCR_GWE;
	writel(tmp , fbi->regs + LCDC_LGWCR);
}

static int imxfb_overlay_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
		   u_int trans, struct fb_info *info)
{
	return 0;
}

static struct fb_ops imxfb_overlay_ops = {
	.fb_setcolreg	= imxfb_overlay_setcolreg,
	.fb_enable	= imxfb_overlay_enable_controller,
	.fb_disable	= imxfb_overlay_disable_controller,
};

static int imxfb_alpha_set(struct device_d *dev, struct param_d *param,
		const char *val)
{
	struct fb_info *overlay = dev->priv;
	struct imxfb_info *fbi = overlay->priv;
	int alpha;
	char alphastr[16];
	unsigned int tmp;

	if (!val)
		return dev_param_set_generic(dev, param, NULL);

	alpha = simple_strtoul(val, NULL, 0);
	alpha &= 0xff;

	tmp = readl(fbi->regs + LCDC_LGWCR);
	tmp &= ~LGWCR_GWAV(0xff);
	tmp |= LGWCR_GWAV(alpha);
	writel(tmp , fbi->regs + LCDC_LGWCR);

	sprintf(alphastr, "%d", alpha);

	dev_param_set_generic(dev, param, alphastr);

	return 0;
}

static int imxfb_register_overlay(struct imxfb_info *fbi, void *fb)
{
	struct fb_info *overlay;
	struct imxfb_rgb *rgb;
	int ret;

	overlay = &fbi->overlay;

	overlay->priv = fbi;
	overlay->mode = fbi->info.mode;
	overlay->xres = fbi->info.xres;
	overlay->yres = fbi->info.yres;
	overlay->bits_per_pixel = fbi->info.bits_per_pixel;
	overlay->fbops = &imxfb_overlay_ops;

	if (fb)
		overlay->screen_base = fb;
	else
		overlay->screen_base = xzalloc(overlay->xres * overlay->yres *
			(overlay->bits_per_pixel >> 3));

	writel((unsigned long)overlay->screen_base, fbi->regs + LCDC_LGWSAR);
	writel(SIZE_XMAX(overlay->xres) | SIZE_YMAX(overlay->yres),
			fbi->regs + LCDC_LGWSR);
	writel(VPW_VPW(overlay->xres * overlay->bits_per_pixel / 8 / 4),
		fbi->regs + LCDC_LGWVPWR);
	writel(0, fbi->regs + LCDC_LGWPR);
	writel(LGWCR_GWAV(0x0), fbi->regs + LCDC_LGWCR);

	switch (overlay->bits_per_pixel) {
	case 32:
		rgb = &def_rgb_18;
		break;
	case 16:
	default:
		if (fbi->pcr & PCR_TFT)
			rgb = &def_rgb_16_tft;
		else
			rgb = &def_rgb_16_stn;
		break;
	case 8:
		rgb = &def_rgb_8;
		break;
	}

	/*
	 * Copy the RGB parameters for this display
	 * from the machine specific parameters.
	 */
	overlay->red    = rgb->red;
	overlay->green  = rgb->green;
	overlay->blue   = rgb->blue;
	overlay->transp = rgb->transp;

	ret = register_framebuffer(overlay);
	if (ret < 0) {
		dev_err(fbi->dev, "failed to register framebuffer\n");
		return ret;
	}

	dev_add_param(&overlay->dev, "alpha", imxfb_alpha_set, NULL, 0);
	dev_set_param(&overlay->dev, "alpha", "0");

	return 0;
}
#endif

static int imxfb_probe(struct device_d *dev)
{
	struct imxfb_info *fbi;
	struct fb_info *info;
	struct imx_fb_platform_data *pdata = dev->platform_data;
	int ret;

	if (!pdata)
		return -ENODEV;

#ifdef CONFIG_ARCH_IMX21
	PCCR0 &= ~(PCCR0_PERCLK3_EN | PCCR0_HCLK_LCDC_EN);
#endif
#ifdef CONFIG_ARCH_IMX27
	PCCR0 &= ~PCCR0_LCDC_EN;
	PCCR1 &= ~PCCR1_HCLK_LCDC;
#endif
#ifdef CONFIG_ARCH_IMX25
	writel(readl(IMX_CCM_BASE + CCM_CGCR0) & ~((1 << 24) | (1 << 7)),
		IMX_CCM_BASE + CCM_CGCR0);
	writel(readl(IMX_CCM_BASE + CCM_CGCR1) & ~(1 << 29),
		IMX_CCM_BASE + CCM_CGCR1);
#endif

	fbi = xzalloc(sizeof(*fbi));
	info = &fbi->info;

	fbi->mode = pdata->mode;
	fbi->regs = (void *)dev->map_base;
	fbi->pcr = pdata->mode->pcr;
	fbi->pwmr = pdata->pwmr;
	fbi->lscr1 = pdata->lscr1;
	fbi->dmacr = pdata->dmacr;
	fbi->enable = pdata->enable;
	fbi->dev = dev;
	info->priv = fbi;
	info->mode = &pdata->mode->mode;
	info->xres = pdata->mode->mode.xres;
	info->yres = pdata->mode->mode.yres;
	info->bits_per_pixel = pdata->mode->bpp;
	info->fbops = &imxfb_ops;

	dev_info(dev, "i.MX Framebuffer driver\n");

	if (pdata->framebuffer)
		fbi->info.screen_base = pdata->framebuffer;
	else
		fbi->info.screen_base = xzalloc(info->xres * info->yres *
			(info->bits_per_pixel >> 3));

	imxfb_activate_var(&fbi->info);

	ret = register_framebuffer(&fbi->info);
	if (ret < 0) {
		dev_err(dev, "failed to register framebuffer\n");
		return ret;
	}
#ifdef CONFIG_IMXFB_DRIVER_VIDEO_IMX_OVERLAY
	imxfb_register_overlay(fbi, pdata->framebuffer_ovl);
#endif
	return 0;
}

static void imxfb_remove(struct device_d *dev)
{
}

static struct driver_d imxfb_driver = {
	.name		= "imxfb",
	.probe		= imxfb_probe,
	.remove		= imxfb_remove,
};

static int imxfb_init(void)
{
	return register_driver(&imxfb_driver);
}

device_initcall(imxfb_init);

