/*
 * Copyright (C) 2008
 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
 *
 * Copyright 2004-2007 Freescale Semiconductor, 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 version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/console.h>
#include <linux/clk.h>
#include <linux/mutex.h>

#include <mach/hardware.h>
#include <mach/ipu.h>
#include <mach/mx3fb.h>

#include <asm/io.h>
#include <asm/uaccess.h>

#define MX3FB_NAME		"mx3_sdc_fb"

#define MX3FB_REG_OFFSET	0xB4

/* SDC Registers */
#define SDC_COM_CONF		(0xB4 - MX3FB_REG_OFFSET)
#define SDC_GW_CTRL		(0xB8 - MX3FB_REG_OFFSET)
#define SDC_FG_POS		(0xBC - MX3FB_REG_OFFSET)
#define SDC_BG_POS		(0xC0 - MX3FB_REG_OFFSET)
#define SDC_CUR_POS		(0xC4 - MX3FB_REG_OFFSET)
#define SDC_PWM_CTRL		(0xC8 - MX3FB_REG_OFFSET)
#define SDC_CUR_MAP		(0xCC - MX3FB_REG_OFFSET)
#define SDC_HOR_CONF		(0xD0 - MX3FB_REG_OFFSET)
#define SDC_VER_CONF		(0xD4 - MX3FB_REG_OFFSET)
#define SDC_SHARP_CONF_1	(0xD8 - MX3FB_REG_OFFSET)
#define SDC_SHARP_CONF_2	(0xDC - MX3FB_REG_OFFSET)

/* Register bits */
#define SDC_COM_TFT_COLOR	0x00000001UL
#define SDC_COM_FG_EN		0x00000010UL
#define SDC_COM_GWSEL		0x00000020UL
#define SDC_COM_GLB_A		0x00000040UL
#define SDC_COM_KEY_COLOR_G	0x00000080UL
#define SDC_COM_BG_EN		0x00000200UL
#define SDC_COM_SHARP		0x00001000UL

#define SDC_V_SYNC_WIDTH_L	0x00000001UL

/* Display Interface registers */
#define DI_DISP_IF_CONF		(0x0124 - MX3FB_REG_OFFSET)
#define DI_DISP_SIG_POL		(0x0128 - MX3FB_REG_OFFSET)
#define DI_SER_DISP1_CONF	(0x012C - MX3FB_REG_OFFSET)
#define DI_SER_DISP2_CONF	(0x0130 - MX3FB_REG_OFFSET)
#define DI_HSP_CLK_PER		(0x0134 - MX3FB_REG_OFFSET)
#define DI_DISP0_TIME_CONF_1	(0x0138 - MX3FB_REG_OFFSET)
#define DI_DISP0_TIME_CONF_2	(0x013C - MX3FB_REG_OFFSET)
#define DI_DISP0_TIME_CONF_3	(0x0140 - MX3FB_REG_OFFSET)
#define DI_DISP1_TIME_CONF_1	(0x0144 - MX3FB_REG_OFFSET)
#define DI_DISP1_TIME_CONF_2	(0x0148 - MX3FB_REG_OFFSET)
#define DI_DISP1_TIME_CONF_3	(0x014C - MX3FB_REG_OFFSET)
#define DI_DISP2_TIME_CONF_1	(0x0150 - MX3FB_REG_OFFSET)
#define DI_DISP2_TIME_CONF_2	(0x0154 - MX3FB_REG_OFFSET)
#define DI_DISP2_TIME_CONF_3	(0x0158 - MX3FB_REG_OFFSET)
#define DI_DISP3_TIME_CONF	(0x015C - MX3FB_REG_OFFSET)
#define DI_DISP0_DB0_MAP	(0x0160 - MX3FB_REG_OFFSET)
#define DI_DISP0_DB1_MAP	(0x0164 - MX3FB_REG_OFFSET)
#define DI_DISP0_DB2_MAP	(0x0168 - MX3FB_REG_OFFSET)
#define DI_DISP0_CB0_MAP	(0x016C - MX3FB_REG_OFFSET)
#define DI_DISP0_CB1_MAP	(0x0170 - MX3FB_REG_OFFSET)
#define DI_DISP0_CB2_MAP	(0x0174 - MX3FB_REG_OFFSET)
#define DI_DISP1_DB0_MAP	(0x0178 - MX3FB_REG_OFFSET)
#define DI_DISP1_DB1_MAP	(0x017C - MX3FB_REG_OFFSET)
#define DI_DISP1_DB2_MAP	(0x0180 - MX3FB_REG_OFFSET)
#define DI_DISP1_CB0_MAP	(0x0184 - MX3FB_REG_OFFSET)
#define DI_DISP1_CB1_MAP	(0x0188 - MX3FB_REG_OFFSET)
#define DI_DISP1_CB2_MAP	(0x018C - MX3FB_REG_OFFSET)
#define DI_DISP2_DB0_MAP	(0x0190 - MX3FB_REG_OFFSET)
#define DI_DISP2_DB1_MAP	(0x0194 - MX3FB_REG_OFFSET)
#define DI_DISP2_DB2_MAP	(0x0198 - MX3FB_REG_OFFSET)
#define DI_DISP2_CB0_MAP	(0x019C - MX3FB_REG_OFFSET)
#define DI_DISP2_CB1_MAP	(0x01A0 - MX3FB_REG_OFFSET)
#define DI_DISP2_CB2_MAP	(0x01A4 - MX3FB_REG_OFFSET)
#define DI_DISP3_B0_MAP		(0x01A8 - MX3FB_REG_OFFSET)
#define DI_DISP3_B1_MAP		(0x01AC - MX3FB_REG_OFFSET)
#define DI_DISP3_B2_MAP		(0x01B0 - MX3FB_REG_OFFSET)
#define DI_DISP_ACC_CC		(0x01B4 - MX3FB_REG_OFFSET)
#define DI_DISP_LLA_CONF	(0x01B8 - MX3FB_REG_OFFSET)
#define DI_DISP_LLA_DATA	(0x01BC - MX3FB_REG_OFFSET)

/* DI_DISP_SIG_POL bits */
#define DI_D3_VSYNC_POL_SHIFT		28
#define DI_D3_HSYNC_POL_SHIFT		27
#define DI_D3_DRDY_SHARP_POL_SHIFT	26
#define DI_D3_CLK_POL_SHIFT		25
#define DI_D3_DATA_POL_SHIFT		24

/* DI_DISP_IF_CONF bits */
#define DI_D3_CLK_IDLE_SHIFT		26
#define DI_D3_CLK_SEL_SHIFT		25
#define DI_D3_DATAMSK_SHIFT		24

enum ipu_panel {
	IPU_PANEL_SHARP_TFT,
	IPU_PANEL_TFT,
};

struct ipu_di_signal_cfg {
	unsigned datamask_en:1;
	unsigned clksel_en:1;
	unsigned clkidle_en:1;
	unsigned data_pol:1;	/* true = inverted */
	unsigned clk_pol:1;	/* true = rising edge */
	unsigned enable_pol:1;
	unsigned Hsync_pol:1;	/* true = active high */
	unsigned Vsync_pol:1;
};

static const struct fb_videomode mx3fb_modedb[] = {
	{
		/* 240x320 @ 60 Hz */
		.name		= "Sharp-QVGA",
		.refresh	= 60,
		.xres		= 240,
		.yres		= 320,
		.pixclock	= 185925,
		.left_margin	= 9,
		.right_margin	= 16,
		.upper_margin	= 7,
		.lower_margin	= 9,
		.hsync_len	= 1,
		.vsync_len	= 1,
		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
				  FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
				  FB_SYNC_CLK_IDLE_EN,
		.vmode		= FB_VMODE_NONINTERLACED,
		.flag		= 0,
	}, {
		/* 240x33 @ 60 Hz */
		.name		= "Sharp-CLI",
		.refresh	= 60,
		.xres		= 240,
		.yres		= 33,
		.pixclock	= 185925,
		.left_margin	= 9,
		.right_margin	= 16,
		.upper_margin	= 7,
		.lower_margin	= 9 + 287,
		.hsync_len	= 1,
		.vsync_len	= 1,
		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE |
				  FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT |
				  FB_SYNC_CLK_IDLE_EN,
		.vmode		= FB_VMODE_NONINTERLACED,
		.flag		= 0,
	}, {
		/* 640x480 @ 60 Hz */
		.name		= "NEC-VGA",
		.refresh	= 60,
		.xres		= 640,
		.yres		= 480,
		.pixclock	= 38255,
		.left_margin	= 144,
		.right_margin	= 0,
		.upper_margin	= 34,
		.lower_margin	= 40,
		.hsync_len	= 1,
		.vsync_len	= 1,
		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
		.vmode		= FB_VMODE_NONINTERLACED,
		.flag		= 0,
	}, {
		/* NTSC TV output */
		.name		= "TV-NTSC",
		.refresh	= 60,
		.xres		= 640,
		.yres		= 480,
		.pixclock	= 37538,
		.left_margin	= 38,
		.right_margin	= 858 - 640 - 38 - 3,
		.upper_margin	= 36,
		.lower_margin	= 518 - 480 - 36 - 1,
		.hsync_len	= 3,
		.vsync_len	= 1,
		.sync		= 0,
		.vmode		= FB_VMODE_NONINTERLACED,
		.flag		= 0,
	}, {
		/* PAL TV output */
		.name		= "TV-PAL",
		.refresh	= 50,
		.xres		= 640,
		.yres		= 480,
		.pixclock	= 37538,
		.left_margin	= 38,
		.right_margin	= 960 - 640 - 38 - 32,
		.upper_margin	= 32,
		.lower_margin	= 555 - 480 - 32 - 3,
		.hsync_len	= 32,
		.vsync_len	= 3,
		.sync		= 0,
		.vmode		= FB_VMODE_NONINTERLACED,
		.flag		= 0,
	}, {
		/* TV output VGA mode, 640x480 @ 65 Hz */
		.name		= "TV-VGA",
		.refresh	= 60,
		.xres		= 640,
		.yres		= 480,
		.pixclock	= 40574,
		.left_margin	= 35,
		.right_margin	= 45,
		.upper_margin	= 9,
		.lower_margin	= 1,
		.hsync_len	= 46,
		.vsync_len	= 5,
		.sync		= 0,
		.vmode		= FB_VMODE_NONINTERLACED,
		.flag		= 0,
	},
};

struct mx3fb_data {
	struct fb_info		*fbi;
	int			backlight_level;
	void __iomem		*reg_base;
	spinlock_t		lock;
	struct device		*dev;

	uint32_t		h_start_width;
	uint32_t		v_start_width;
};

struct dma_chan_request {
	struct mx3fb_data	*mx3fb;
	enum ipu_channel	id;
};

/* MX3 specific framebuffer information. */
struct mx3fb_info {
	int				blank;
	enum ipu_channel		ipu_ch;
	uint32_t			cur_ipu_buf;

	u32				pseudo_palette[16];

	struct completion		flip_cmpl;
	struct mutex			mutex;	/* Protects fb-ops */
	struct mx3fb_data		*mx3fb;
	struct idmac_channel		*idmac_channel;
	struct dma_async_tx_descriptor	*txd;
	dma_cookie_t			cookie;
	struct scatterlist		sg[2];

	u32				sync;	/* preserve var->sync flags */
};

static void mx3fb_dma_done(void *);

/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */
static const char *fb_mode;
static unsigned long default_bpp = 16;

static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg)
{
	return __raw_readl(mx3fb->reg_base + reg);
}

static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg)
{
	__raw_writel(value, mx3fb->reg_base + reg);
}

static const uint32_t di_mappings[] = {
	0x1600AAAA, 0x00E05555, 0x00070000, 3,	/* RGB888 */
	0x0005000F, 0x000B000F, 0x0011000F, 1,	/* RGB666 */
	0x0011000F, 0x000B000F, 0x0005000F, 1,	/* BGR666 */
	0x0004003F, 0x000A000F, 0x000F003F, 1	/* RGB565 */
};

static void sdc_fb_init(struct mx3fb_info *fbi)
{
	struct mx3fb_data *mx3fb = fbi->mx3fb;
	uint32_t reg;

	reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);

	mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF);
}

/* Returns enabled flag before uninit */
static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi)
{
	struct mx3fb_data *mx3fb = fbi->mx3fb;
	uint32_t reg;

	reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);

	mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF);

	return reg & SDC_COM_BG_EN;
}

static void sdc_enable_channel(struct mx3fb_info *mx3_fbi)
{
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
	struct idmac_channel *ichan = mx3_fbi->idmac_channel;
	struct dma_chan *dma_chan = &ichan->dma_chan;
	unsigned long flags;
	dma_cookie_t cookie;

	if (mx3_fbi->txd)
		dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi,
			to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg);
	else
		dev_dbg(mx3fb->dev, "mx3fbi %p, txd = NULL\n", mx3_fbi);

	/* This enables the channel */
	if (mx3_fbi->cookie < 0) {
		mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan,
		      &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
		if (!mx3_fbi->txd) {
			dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n",
				dma_chan->chan_id);
			return;
		}

		mx3_fbi->txd->callback_param	= mx3_fbi->txd;
		mx3_fbi->txd->callback		= mx3fb_dma_done;

		cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd);
		dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__,
		       mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
	} else {
		if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) {
			dev_err(mx3fb->dev, "Cannot enable channel %d\n",
				dma_chan->chan_id);
			return;
		}

		/* Just re-activate the same buffer */
		dma_async_issue_pending(dma_chan);
		cookie = mx3_fbi->cookie;
		dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__,
		       mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+');
	}

	if (cookie >= 0) {
		spin_lock_irqsave(&mx3fb->lock, flags);
		sdc_fb_init(mx3_fbi);
		mx3_fbi->cookie = cookie;
		spin_unlock_irqrestore(&mx3fb->lock, flags);
	}

	/*
	 * Attention! Without this msleep the channel keeps generating
	 * interrupts. Next sdc_set_brightness() is going to be called
	 * from mx3fb_blank().
	 */
	msleep(2);
}

static void sdc_disable_channel(struct mx3fb_info *mx3_fbi)
{
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
	uint32_t enabled;
	unsigned long flags;

	spin_lock_irqsave(&mx3fb->lock, flags);

	enabled = sdc_fb_uninit(mx3_fbi);

	spin_unlock_irqrestore(&mx3fb->lock, flags);

	mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan);
	mx3_fbi->txd = NULL;
	mx3_fbi->cookie = -EINVAL;
}

/**
 * sdc_set_window_pos() - set window position of the respective plane.
 * @mx3fb:	mx3fb context.
 * @channel:	IPU DMAC channel ID.
 * @x_pos:	X coordinate relative to the top left corner to place window at.
 * @y_pos:	Y coordinate relative to the top left corner to place window at.
 * @return:	0 on success or negative error code on failure.
 */
static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel,
			      int16_t x_pos, int16_t y_pos)
{
	if (channel != IDMAC_SDC_0)
		return -EINVAL;

	x_pos += mx3fb->h_start_width;
	y_pos += mx3fb->v_start_width;

	mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS);
	return 0;
}

/**
 * sdc_init_panel() - initialize a synchronous LCD panel.
 * @mx3fb:		mx3fb context.
 * @panel:		panel type.
 * @pixel_clk:		desired pixel clock frequency in Hz.
 * @width:		width of panel in pixels.
 * @height:		height of panel in pixels.
 * @pixel_fmt:		pixel format of buffer as FOURCC ASCII code.
 * @h_start_width:	number of pixel clocks between the HSYNC signal pulse
 *			and the start of valid data.
 * @h_sync_width:	width of the HSYNC signal in units of pixel clocks.
 * @h_end_width:	number of pixel clocks between the end of valid data
 *			and the HSYNC signal for next line.
 * @v_start_width:	number of lines between the VSYNC signal pulse and the
 *			start of valid data.
 * @v_sync_width:	width of the VSYNC signal in units of lines
 * @v_end_width:	number of lines between the end of valid data and the
 *			VSYNC signal for next frame.
 * @sig:		bitfield of signal polarities for LCD interface.
 * @return:		0 on success or negative error code on failure.
 */
static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel,
			  uint32_t pixel_clk,
			  uint16_t width, uint16_t height,
			  enum pixel_fmt pixel_fmt,
			  uint16_t h_start_width, uint16_t h_sync_width,
			  uint16_t h_end_width, uint16_t v_start_width,
			  uint16_t v_sync_width, uint16_t v_end_width,
			  struct ipu_di_signal_cfg sig)
{
	unsigned long lock_flags;
	uint32_t reg;
	uint32_t old_conf;
	uint32_t div;
	struct clk *ipu_clk;

	dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height);

	if (v_sync_width == 0 || h_sync_width == 0)
		return -EINVAL;

	/* Init panel size and blanking periods */
	reg = ((uint32_t) (h_sync_width - 1) << 26) |
		((uint32_t) (width + h_start_width + h_end_width - 1) << 16);
	mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF);

#ifdef DEBUG
	printk(KERN_CONT " hor_conf %x,", reg);
#endif

	reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L |
	    ((uint32_t) (height + v_start_width + v_end_width - 1) << 16);
	mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF);

#ifdef DEBUG
	printk(KERN_CONT " ver_conf %x\n", reg);
#endif

	mx3fb->h_start_width = h_start_width;
	mx3fb->v_start_width = v_start_width;

	switch (panel) {
	case IPU_PANEL_SHARP_TFT:
		mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1);
		mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2);
		mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF);
		break;
	case IPU_PANEL_TFT:
		mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF);
		break;
	default:
		return -EINVAL;
	}

	/* Init clocking */

	/*
	 * Calculate divider: fractional part is 4 bits so simply multiple by
	 * 2^4 to get fractional part, as long as we stay under ~250MHz and on
	 * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz
	 */
	ipu_clk = clk_get(mx3fb->dev, NULL);
	if (!IS_ERR(ipu_clk)) {
		div = clk_get_rate(ipu_clk) * 16 / pixel_clk;
		clk_put(ipu_clk);
	} else {
		div = 0;
	}

	if (div < 0x40) {	/* Divider less than 4 */
		dev_dbg(mx3fb->dev,
			"InitPanel() - Pixel clock divider less than 4\n");
		div = 0x40;
	}

	dev_dbg(mx3fb->dev, "pixel clk = %u, divider %u.%u\n",
		pixel_clk, div >> 4, (div & 7) * 125);

	spin_lock_irqsave(&mx3fb->lock, lock_flags);

	/*
	 * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits
	 * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing
	 * debug. DISP3_IF_CLK_UP_WR is 0
	 */
	mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF);

	/* DI settings */
	old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF;
	old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT |
		sig.clksel_en << DI_D3_CLK_SEL_SHIFT |
		sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT;
	mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF);

	old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF;
	old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT |
		sig.clk_pol << DI_D3_CLK_POL_SHIFT |
		sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT |
		sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT |
		sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT;
	mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL);

	switch (pixel_fmt) {
	case IPU_PIX_FMT_RGB24:
		mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP);
		mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
			     ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC);
		break;
	case IPU_PIX_FMT_RGB666:
		mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP);
		mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
			     ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC);
		break;
	case IPU_PIX_FMT_BGR666:
		mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP);
		mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
			     ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC);
		break;
	default:
		mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP);
		mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP);
		mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) |
			     ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC);
		break;
	}

	spin_unlock_irqrestore(&mx3fb->lock, lock_flags);

	dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n",
		mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF));
	dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n",
		mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL));
	dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n",
		mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF));

	return 0;
}

/**
 * sdc_set_color_key() - set the transparent color key for SDC graphic plane.
 * @mx3fb:	mx3fb context.
 * @channel:	IPU DMAC channel ID.
 * @enable:	boolean to enable or disable color keyl.
 * @color_key:	24-bit RGB color to use as transparent color key.
 * @return:	0 on success or negative error code on failure.
 */
static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel,
			     bool enable, uint32_t color_key)
{
	uint32_t reg, sdc_conf;
	unsigned long lock_flags;

	spin_lock_irqsave(&mx3fb->lock, lock_flags);

	sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
	if (channel == IDMAC_SDC_0)
		sdc_conf &= ~SDC_COM_GWSEL;
	else
		sdc_conf |= SDC_COM_GWSEL;

	if (enable) {
		reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L;
		mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL),
			     SDC_GW_CTRL);

		sdc_conf |= SDC_COM_KEY_COLOR_G;
	} else {
		sdc_conf &= ~SDC_COM_KEY_COLOR_G;
	}
	mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF);

	spin_unlock_irqrestore(&mx3fb->lock, lock_flags);

	return 0;
}

/**
 * sdc_set_global_alpha() - set global alpha blending modes.
 * @mx3fb:	mx3fb context.
 * @enable:	boolean to enable or disable global alpha blending. If disabled,
 *		per pixel blending is used.
 * @alpha:	global alpha value.
 * @return:	0 on success or negative error code on failure.
 */
static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha)
{
	uint32_t reg;
	unsigned long lock_flags;

	spin_lock_irqsave(&mx3fb->lock, lock_flags);

	if (enable) {
		reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL;
		mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL);

		reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
		mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF);
	} else {
		reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF);
		mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF);
	}

	spin_unlock_irqrestore(&mx3fb->lock, lock_flags);

	return 0;
}

static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)
{
	dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value);
	/* This might be board-specific */
	mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL);
	return;
}

static uint32_t bpp_to_pixfmt(int bpp)
{
	uint32_t pixfmt = 0;
	switch (bpp) {
	case 24:
		pixfmt = IPU_PIX_FMT_BGR24;
		break;
	case 32:
		pixfmt = IPU_PIX_FMT_BGR32;
		break;
	case 16:
		pixfmt = IPU_PIX_FMT_RGB565;
		break;
	}
	return pixfmt;
}

static int mx3fb_blank(int blank, struct fb_info *fbi);
static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
				  bool lock);
static int mx3fb_unmap_video_memory(struct fb_info *fbi);

/**
 * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings.
 * @info:	framebuffer information pointer
 * @return:	0 on success or negative error code on failure.
 */
static int mx3fb_set_fix(struct fb_info *fbi)
{
	struct fb_fix_screeninfo *fix = &fbi->fix;
	struct fb_var_screeninfo *var = &fbi->var;

	strncpy(fix->id, "DISP3 BG", 8);

	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;

	fix->type = FB_TYPE_PACKED_PIXELS;
	fix->accel = FB_ACCEL_NONE;
	fix->visual = FB_VISUAL_TRUECOLOR;
	fix->xpanstep = 1;
	fix->ypanstep = 1;

	return 0;
}

static void mx3fb_dma_done(void *arg)
{
	struct idmac_tx_desc *tx_desc = to_tx_desc(arg);
	struct dma_chan *chan = tx_desc->txd.chan;
	struct idmac_channel *ichannel = to_idmac_chan(chan);
	struct mx3fb_data *mx3fb = ichannel->client;
	struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;

	dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq);

	/* We only need one interrupt, it will be re-enabled as needed */
	disable_irq_nosync(ichannel->eof_irq);

	complete(&mx3_fbi->flip_cmpl);
}

static int __set_par(struct fb_info *fbi, bool lock)
{
	u32 mem_len;
	struct ipu_di_signal_cfg sig_cfg;
	enum ipu_panel mode = IPU_PANEL_TFT;
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
	struct idmac_channel *ichan = mx3_fbi->idmac_channel;
	struct idmac_video_param *video = &ichan->params.video;
	struct scatterlist *sg = mx3_fbi->sg;

	/* Total cleanup */
	if (mx3_fbi->txd)
		sdc_disable_channel(mx3_fbi);

	mx3fb_set_fix(fbi);

	mem_len = fbi->var.yres_virtual * fbi->fix.line_length;
	if (mem_len > fbi->fix.smem_len) {
		if (fbi->fix.smem_start)
			mx3fb_unmap_video_memory(fbi);

		if (mx3fb_map_video_memory(fbi, mem_len, lock) < 0)
			return -ENOMEM;
	}

	sg_init_table(&sg[0], 1);
	sg_init_table(&sg[1], 1);

	sg_dma_address(&sg[0]) = fbi->fix.smem_start;
	sg_set_page(&sg[0], virt_to_page(fbi->screen_base),
		    fbi->fix.smem_len,
		    offset_in_page(fbi->screen_base));

	if (mx3_fbi->ipu_ch == IDMAC_SDC_0) {
		memset(&sig_cfg, 0, sizeof(sig_cfg));
		if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)
			sig_cfg.Hsync_pol = true;
		if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)
			sig_cfg.Vsync_pol = true;
		if (fbi->var.sync & FB_SYNC_CLK_INVERT)
			sig_cfg.clk_pol = true;
		if (fbi->var.sync & FB_SYNC_DATA_INVERT)
			sig_cfg.data_pol = true;
		if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH)
			sig_cfg.enable_pol = true;
		if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
			sig_cfg.clkidle_en = true;
		if (fbi->var.sync & FB_SYNC_CLK_SEL_EN)
			sig_cfg.clksel_en = true;
		if (fbi->var.sync & FB_SYNC_SHARP_MODE)
			mode = IPU_PANEL_SHARP_TFT;

		dev_dbg(fbi->device, "pixclock = %ul Hz\n",
			(u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL));

		if (sdc_init_panel(mx3fb, mode,
				   (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
				   fbi->var.xres, fbi->var.yres,
				   (fbi->var.sync & FB_SYNC_SWAP_RGB) ?
				   IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666,
				   fbi->var.left_margin,
				   fbi->var.hsync_len,
				   fbi->var.right_margin +
				   fbi->var.hsync_len,
				   fbi->var.upper_margin,
				   fbi->var.vsync_len,
				   fbi->var.lower_margin +
				   fbi->var.vsync_len, sig_cfg) != 0) {
			dev_err(fbi->device,
				"mx3fb: Error initializing panel.\n");
			return -EINVAL;
		}
	}

	sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0);

	mx3_fbi->cur_ipu_buf	= 0;

	video->out_pixel_fmt	= bpp_to_pixfmt(fbi->var.bits_per_pixel);
	video->out_width	= fbi->var.xres;
	video->out_height	= fbi->var.yres;
	video->out_stride	= fbi->var.xres_virtual;

	if (mx3_fbi->blank == FB_BLANK_UNBLANK)
		sdc_enable_channel(mx3_fbi);

	return 0;
}

/**
 * mx3fb_set_par() - set framebuffer parameters and change the operating mode.
 * @fbi:	framebuffer information pointer.
 * @return:	0 on success or negative error code on failure.
 */
static int mx3fb_set_par(struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;
	struct idmac_channel *ichan = mx3_fbi->idmac_channel;
	int ret;

	dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+');

	mutex_lock(&mx3_fbi->mutex);

	ret = __set_par(fbi, true);

	mutex_unlock(&mx3_fbi->mutex);

	return ret;
}

/**
 * mx3fb_check_var() - check and adjust framebuffer variable parameters.
 * @var:	framebuffer variable parameters
 * @fbi:	framebuffer information pointer
 */
static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	u32 vtotal;
	u32 htotal;

	dev_dbg(fbi->device, "%s\n", __func__);

	if (var->xres_virtual < var->xres)
		var->xres_virtual = var->xres;
	if (var->yres_virtual < var->yres)
		var->yres_virtual = var->yres;

	if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) &&
	    (var->bits_per_pixel != 16))
		var->bits_per_pixel = default_bpp;

	switch (var->bits_per_pixel) {
	case 16:
		var->red.length = 5;
		var->red.offset = 11;
		var->red.msb_right = 0;

		var->green.length = 6;
		var->green.offset = 5;
		var->green.msb_right = 0;

		var->blue.length = 5;
		var->blue.offset = 0;
		var->blue.msb_right = 0;

		var->transp.length = 0;
		var->transp.offset = 0;
		var->transp.msb_right = 0;
		break;
	case 24:
		var->red.length = 8;
		var->red.offset = 16;
		var->red.msb_right = 0;

		var->green.length = 8;
		var->green.offset = 8;
		var->green.msb_right = 0;

		var->blue.length = 8;
		var->blue.offset = 0;
		var->blue.msb_right = 0;

		var->transp.length = 0;
		var->transp.offset = 0;
		var->transp.msb_right = 0;
		break;
	case 32:
		var->red.length = 8;
		var->red.offset = 16;
		var->red.msb_right = 0;

		var->green.length = 8;
		var->green.offset = 8;
		var->green.msb_right = 0;

		var->blue.length = 8;
		var->blue.offset = 0;
		var->blue.msb_right = 0;

		var->transp.length = 8;
		var->transp.offset = 24;
		var->transp.msb_right = 0;
		break;
	}

	if (var->pixclock < 1000) {
		htotal = var->xres + var->right_margin + var->hsync_len +
		    var->left_margin;
		vtotal = var->yres + var->lower_margin + var->vsync_len +
		    var->upper_margin;
		var->pixclock = (vtotal * htotal * 6UL) / 100UL;
		var->pixclock = KHZ2PICOS(var->pixclock);
		dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n",
			var->pixclock);
	}

	var->height = -1;
	var->width = -1;
	var->grayscale = 0;

	/* Preserve sync flags */
	var->sync |= mx3_fbi->sync;
	mx3_fbi->sync |= var->sync;

	return 0;
}

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

static int mx3fb_setcolreg(unsigned int regno, unsigned int red,
			   unsigned int green, unsigned int blue,
			   unsigned int trans, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	u32 val;
	int ret = 1;

	dev_dbg(fbi->device, "%s, regno = %u\n", __func__, regno);

	mutex_lock(&mx3_fbi->mutex);
	/*
	 * If greyscale is true, then we convert the RGB value
	 * to greyscale no matter what visual we are using.
	 */
	if (fbi->var.grayscale)
		red = green = blue = (19595 * red + 38470 * green +
				      7471 * blue) >> 16;
	switch (fbi->fix.visual) {
	case FB_VISUAL_TRUECOLOR:
		/*
		 * 16-bit True Colour.  We encode the RGB value
		 * according to the RGB bitfield information.
		 */
		if (regno < 16) {
			u32 *pal = fbi->pseudo_palette;

			val = chan_to_field(red, &fbi->var.red);
			val |= chan_to_field(green, &fbi->var.green);
			val |= chan_to_field(blue, &fbi->var.blue);

			pal[regno] = val;

			ret = 0;
		}
		break;

	case FB_VISUAL_STATIC_PSEUDOCOLOR:
	case FB_VISUAL_PSEUDOCOLOR:
		break;
	}
	mutex_unlock(&mx3_fbi->mutex);

	return ret;
}

static void __blank(int blank, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct mx3fb_data *mx3fb = mx3_fbi->mx3fb;

	mx3_fbi->blank = blank;

	switch (blank) {
	case FB_BLANK_POWERDOWN:
	case FB_BLANK_VSYNC_SUSPEND:
	case FB_BLANK_HSYNC_SUSPEND:
	case FB_BLANK_NORMAL:
		sdc_set_brightness(mx3fb, 0);
		memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
		/* Give LCD time to update - enough for 50 and 60 Hz */
		msleep(25);
		sdc_disable_channel(mx3_fbi);
		break;
	case FB_BLANK_UNBLANK:
		sdc_enable_channel(mx3_fbi);
		sdc_set_brightness(mx3fb, mx3fb->backlight_level);
		break;
	}
}

/**
 * mx3fb_blank() - blank the display.
 */
static int mx3fb_blank(int blank, struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;

	dev_dbg(fbi->device, "%s, blank = %d, base %p, len %u\n", __func__,
		blank, fbi->screen_base, fbi->fix.smem_len);

	if (mx3_fbi->blank == blank)
		return 0;

	mutex_lock(&mx3_fbi->mutex);
	__blank(blank, fbi);
	mutex_unlock(&mx3_fbi->mutex);

	return 0;
}

/**
 * mx3fb_pan_display() - pan or wrap the display
 * @var:	variable screen buffer information.
 * @info:	framebuffer information pointer.
 *
 * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag
 */
static int mx3fb_pan_display(struct fb_var_screeninfo *var,
			     struct fb_info *fbi)
{
	struct mx3fb_info *mx3_fbi = fbi->par;
	u32 y_bottom;
	unsigned long base;
	off_t offset;
	dma_cookie_t cookie;
	struct scatterlist *sg = mx3_fbi->sg;
	struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan;
	struct dma_async_tx_descriptor *txd;
	int ret;

	dev_dbg(fbi->device, "%s [%c]\n", __func__,
		list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+');

	if (var->xoffset > 0) {
		dev_dbg(fbi->device, "x panning not supported\n");
		return -EINVAL;
	}

	if (fbi->var.xoffset == var->xoffset &&
	    fbi->var.yoffset == var->yoffset)
		return 0;	/* No change, do nothing */

	y_bottom = var->yoffset;

	if (!(var->vmode & FB_VMODE_YWRAP))
		y_bottom += var->yres;

	if (y_bottom > fbi->var.yres_virtual)
		return -EINVAL;

	mutex_lock(&mx3_fbi->mutex);

	offset = (var->yoffset * var->xres_virtual + var->xoffset) *
		(var->bits_per_pixel / 8);
	base = fbi->fix.smem_start + offset;

	dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
		mx3_fbi->cur_ipu_buf, base);

	/*
	 * We enable the End of Frame interrupt, which will free a tx-descriptor,
	 * which we will need for the next device_prep_slave_sg(). The
	 * IRQ-handler will disable the IRQ again.
	 */
	init_completion(&mx3_fbi->flip_cmpl);
	enable_irq(mx3_fbi->idmac_channel->eof_irq);

	ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10);
	if (ret <= 0) {
		mutex_unlock(&mx3_fbi->mutex);
		dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ?
			 "user interrupt" : "timeout");
		disable_irq(mx3_fbi->idmac_channel->eof_irq);
		return ret ? : -ETIMEDOUT;
	}

	mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf;

	sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base;
	sg_set_page(&sg[mx3_fbi->cur_ipu_buf],
		    virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len,
		    offset_in_page(fbi->screen_base + offset));

	if (mx3_fbi->txd)
		async_tx_ack(mx3_fbi->txd);

	txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg +
		mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT);
	if (!txd) {
		dev_err(fbi->device,
			"Error preparing a DMA transaction descriptor.\n");
		mutex_unlock(&mx3_fbi->mutex);
		return -EIO;
	}

	txd->callback_param	= txd;
	txd->callback		= mx3fb_dma_done;

	/*
	 * Emulate original mx3fb behaviour: each new call to idmac_tx_submit()
	 * should switch to another buffer
	 */
	cookie = txd->tx_submit(txd);
	dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie);
	if (cookie < 0) {
		dev_err(fbi->device,
			"Error updating SDC buf %d to address=0x%08lX\n",
			mx3_fbi->cur_ipu_buf, base);
		mutex_unlock(&mx3_fbi->mutex);
		return -EIO;
	}

	mx3_fbi->txd = txd;

	fbi->var.xoffset = var->xoffset;
	fbi->var.yoffset = var->yoffset;

	if (var->vmode & FB_VMODE_YWRAP)
		fbi->var.vmode |= FB_VMODE_YWRAP;
	else
		fbi->var.vmode &= ~FB_VMODE_YWRAP;

	mutex_unlock(&mx3_fbi->mutex);

	dev_dbg(fbi->device, "Update complete\n");

	return 0;
}

/*
 * This structure contains the pointers to the control functions that are
 * invoked by the core framebuffer driver to perform operations like
 * blitting, rectangle filling, copy regions and cursor definition.
 */
static struct fb_ops mx3fb_ops = {
	.owner = THIS_MODULE,
	.fb_set_par = mx3fb_set_par,
	.fb_check_var = mx3fb_check_var,
	.fb_setcolreg = mx3fb_setcolreg,
	.fb_pan_display = mx3fb_pan_display,
	.fb_fillrect = cfb_fillrect,
	.fb_copyarea = cfb_copyarea,
	.fb_imageblit = cfb_imageblit,
	.fb_blank = mx3fb_blank,
};

#ifdef CONFIG_PM
/*
 * Power management hooks.      Note that we won't be called from IRQ context,
 * unlike the blank functions above, so we may sleep.
 */

/*
 * Suspends the framebuffer and blanks the screen. Power management support
 */
static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
{
	struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
	struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;

	acquire_console_sem();
	fb_set_suspend(mx3fb->fbi, 1);
	release_console_sem();

	if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
		sdc_disable_channel(mx3_fbi);
		sdc_set_brightness(mx3fb, 0);

	}
	return 0;
}

/*
 * Resumes the framebuffer and unblanks the screen. Power management support
 */
static int mx3fb_resume(struct platform_device *pdev)
{
	struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
	struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;

	if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
		sdc_enable_channel(mx3_fbi);
		sdc_set_brightness(mx3fb, mx3fb->backlight_level);
	}

	acquire_console_sem();
	fb_set_suspend(mx3fb->fbi, 0);
	release_console_sem();

	return 0;
}
#else
#define mx3fb_suspend   NULL
#define mx3fb_resume    NULL
#endif

/*
 * Main framebuffer functions
 */

/**
 * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer.
 * @fbi:	framebuffer information pointer
 * @mem_len:	length of mapped memory
 * @lock:	do not lock during initialisation
 * @return:	Error code indicating success or failure
 *
 * This buffer is remapped into a non-cached, non-buffered, memory region to
 * allow palette and pixel writes to occur without flushing the cache. Once this
 * area is remapped, all virtual memory access to the video memory should occur
 * at the new region.
 */
static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,
				  bool lock)
{
	int retval = 0;
	dma_addr_t addr;

	fbi->screen_base = dma_alloc_writecombine(fbi->device,
						  mem_len,
						  &addr, GFP_DMA);

	if (!fbi->screen_base) {
		dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",
			mem_len);
		retval = -EBUSY;
		goto err0;
	}

	if (lock)
		mutex_lock(&fbi->mm_lock);
	fbi->fix.smem_start = addr;
	fbi->fix.smem_len = mem_len;
	if (lock)
		mutex_unlock(&fbi->mm_lock);

	dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",
		(uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);

	fbi->screen_size = fbi->fix.smem_len;

	/* Clear the screen */
	memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);

	return 0;

err0:
	fbi->fix.smem_len = 0;
	fbi->fix.smem_start = 0;
	fbi->screen_base = NULL;
	return retval;
}

/**
 * mx3fb_unmap_video_memory() - de-allocate frame buffer memory.
 * @fbi:	framebuffer information pointer
 * @return:	error code indicating success or failure
 */
static int mx3fb_unmap_video_memory(struct fb_info *fbi)
{
	dma_free_writecombine(fbi->device, fbi->fix.smem_len,
			      fbi->screen_base, fbi->fix.smem_start);

	fbi->screen_base = 0;
	mutex_lock(&fbi->mm_lock);
	fbi->fix.smem_start = 0;
	fbi->fix.smem_len = 0;
	mutex_unlock(&fbi->mm_lock);
	return 0;
}

/**
 * mx3fb_init_fbinfo() - initialize framebuffer information object.
 * @return:	initialized framebuffer structure.
 */
static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)
{
	struct fb_info *fbi;
	struct mx3fb_info *mx3fbi;
	int ret;

	/* Allocate sufficient memory for the fb structure */
	fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev);
	if (!fbi)
		return NULL;

	mx3fbi			= fbi->par;
	mx3fbi->cookie		= -EINVAL;
	mx3fbi->cur_ipu_buf	= 0;

	fbi->var.activate	= FB_ACTIVATE_NOW;

	fbi->fbops		= ops;
	fbi->flags		= FBINFO_FLAG_DEFAULT;
	fbi->pseudo_palette	= mx3fbi->pseudo_palette;

	mutex_init(&mx3fbi->mutex);

	/* Allocate colormap */
	ret = fb_alloc_cmap(&fbi->cmap, 16, 0);
	if (ret < 0) {
		framebuffer_release(fbi);
		return NULL;
	}

	return fbi;
}

static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)
{
	struct device *dev = mx3fb->dev;
	struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data;
	const char *name = mx3fb_pdata->name;
	unsigned int irq;
	struct fb_info *fbi;
	struct mx3fb_info *mx3fbi;
	const struct fb_videomode *mode;
	int ret, num_modes;

	ichan->client = mx3fb;
	irq = ichan->eof_irq;

	if (ichan->dma_chan.chan_id != IDMAC_SDC_0)
		return -EINVAL;

	fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops);
	if (!fbi)
		return -ENOMEM;

	if (!fb_mode)
		fb_mode = name;

	if (!fb_mode) {
		ret = -EINVAL;
		goto emode;
	}

	if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {
		mode = mx3fb_pdata->mode;
		num_modes = mx3fb_pdata->num_modes;
	} else {
		mode = mx3fb_modedb;
		num_modes = ARRAY_SIZE(mx3fb_modedb);
	}

	if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,
			  num_modes, NULL, default_bpp)) {
		ret = -EBUSY;
		goto emode;
	}

	fb_videomode_to_modelist(mode, num_modes, &fbi->modelist);

	/* Default Y virtual size is 2x panel size */
	fbi->var.yres_virtual = fbi->var.yres * 2;

	mx3fb->fbi = fbi;

	/* set Display Interface clock period */
	mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER);
	/* Might need to trigger HSP clock change - see 44.3.3.8.5 */

	sdc_set_brightness(mx3fb, 255);
	sdc_set_global_alpha(mx3fb, true, 0xFF);
	sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0);

	mx3fbi			= fbi->par;
	mx3fbi->idmac_channel	= ichan;
	mx3fbi->ipu_ch		= ichan->dma_chan.chan_id;
	mx3fbi->mx3fb		= mx3fb;
	mx3fbi->blank		= FB_BLANK_NORMAL;

	init_completion(&mx3fbi->flip_cmpl);
	disable_irq(ichan->eof_irq);
	dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);
	ret = __set_par(fbi, false);
	if (ret < 0)
		goto esetpar;

	__blank(FB_BLANK_UNBLANK, fbi);

	dev_info(dev, "registered, using mode %s\n", fb_mode);

	ret = register_framebuffer(fbi);
	if (ret < 0)
		goto erfb;

	return 0;

erfb:
esetpar:
emode:
	fb_dealloc_cmap(&fbi->cmap);
	framebuffer_release(fbi);

	return ret;
}

static bool chan_filter(struct dma_chan *chan, void *arg)
{
	struct dma_chan_request *rq = arg;
	struct device *dev;
	struct mx3fb_platform_data *mx3fb_pdata;

	if (!rq)
		return false;

	dev = rq->mx3fb->dev;
	mx3fb_pdata = dev->platform_data;

	return rq->id == chan->chan_id &&
		mx3fb_pdata->dma_dev == chan->device->dev;
}

static void release_fbi(struct fb_info *fbi)
{
	mx3fb_unmap_video_memory(fbi);

	fb_dealloc_cmap(&fbi->cmap);

	unregister_framebuffer(fbi);
	framebuffer_release(fbi);
}

static int mx3fb_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	int ret;
	struct resource *sdc_reg;
	struct mx3fb_data *mx3fb;
	dma_cap_mask_t mask;
	struct dma_chan *chan;
	struct dma_chan_request rq;

	/*
	 * Display Interface (DI) and Synchronous Display Controller (SDC)
	 * registers
	 */
	sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!sdc_reg)
		return -EINVAL;

	mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL);
	if (!mx3fb)
		return -ENOMEM;

	spin_lock_init(&mx3fb->lock);

	mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg));
	if (!mx3fb->reg_base) {
		ret = -ENOMEM;
		goto eremap;
	}

	pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end,
		 mx3fb->reg_base);

	/* IDMAC interface */
	dmaengine_get();

	mx3fb->dev = dev;
	platform_set_drvdata(pdev, mx3fb);

	rq.mx3fb = mx3fb;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);
	dma_cap_set(DMA_PRIVATE, mask);
	rq.id = IDMAC_SDC_0;
	chan = dma_request_channel(mask, chan_filter, &rq);
	if (!chan) {
		ret = -EBUSY;
		goto ersdc0;
	}

	mx3fb->backlight_level = 255;

	ret = init_fb_chan(mx3fb, to_idmac_chan(chan));
	if (ret < 0)
		goto eisdc0;

	return 0;

eisdc0:
	dma_release_channel(chan);
ersdc0:
	dmaengine_put();
	iounmap(mx3fb->reg_base);
eremap:
	kfree(mx3fb);
	dev_err(dev, "mx3fb: failed to register fb\n");
	return ret;
}

static int mx3fb_remove(struct platform_device *dev)
{
	struct mx3fb_data *mx3fb = platform_get_drvdata(dev);
	struct fb_info *fbi = mx3fb->fbi;
	struct mx3fb_info *mx3_fbi = fbi->par;
	struct dma_chan *chan;

	chan = &mx3_fbi->idmac_channel->dma_chan;
	release_fbi(fbi);

	dma_release_channel(chan);
	dmaengine_put();

	iounmap(mx3fb->reg_base);
	kfree(mx3fb);
	return 0;
}

static struct platform_driver mx3fb_driver = {
	.driver = {
		   .name = MX3FB_NAME,
	},
	.probe = mx3fb_probe,
	.remove = mx3fb_remove,
	.suspend = mx3fb_suspend,
	.resume = mx3fb_resume,
};

/*
 * Parse user specified options (`video=mx3fb:')
 * example:
 * 	video=mx3fb:bpp=16
 */
static int __init mx3fb_setup(void)
{
#ifndef MODULE
	char *opt, *options = NULL;

	if (fb_get_options("mx3fb", &options))
		return -ENODEV;

	if (!options || !*options)
		return 0;

	while ((opt = strsep(&options, ",")) != NULL) {
		if (!*opt)
			continue;
		if (!strncmp(opt, "bpp=", 4))
			default_bpp = simple_strtoul(opt + 4, NULL, 0);
		else
			fb_mode = opt;
	}
#endif

	return 0;
}

static int __init mx3fb_init(void)
{
	int ret = mx3fb_setup();

	if (ret < 0)
		return ret;

	ret = platform_driver_register(&mx3fb_driver);
	return ret;
}

static void __exit mx3fb_exit(void)
{
	platform_driver_unregister(&mx3fb_driver);
}

module_init(mx3fb_init);
module_exit(mx3fb_exit);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("MX3 framebuffer driver");
MODULE_ALIAS("platform:" MX3FB_NAME);
MODULE_LICENSE("GPL v2");
