/*
 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 *  Freescale DIU Frame Buffer device driver
 *
 *  Authors: Hongjun Chen <hong-jun.chen@freescale.com>
 *           Paul Widmer <paul.widmer@freescale.com>
 *           Srikanth Srinivasan <srikanth.srinivasan@freescale.com>
 *           York Sun <yorksun@freescale.com>
 *
 *   Based on imxfb.c Copyright (C) 2004 S.Hauer, Pengutronix
 *
 * 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.
 *
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/clk.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/spinlock.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>

#include <sysdev/fsl_soc.h>
#include <linux/fsl-diu-fb.h>
#include "edid.h"

#define NUM_AOIS	5	/* 1 for plane 0, 2 for planes 1 & 2 each */

/* HW cursor parameters */
#define MAX_CURS		32

/* INT_STATUS/INT_MASK field descriptions */
#define INT_VSYNC	0x01	/* Vsync interrupt  */
#define INT_VSYNC_WB	0x02	/* Vsync interrupt for write back operation */
#define INT_UNDRUN	0x04	/* Under run exception interrupt */
#define INT_PARERR	0x08	/* Display parameters error interrupt */
#define INT_LS_BF_VS	0x10	/* Lines before vsync. interrupt */

/*
 * List of supported video modes
 *
 * The first entry is the default video mode.  The remain entries are in
 * order if increasing resolution and frequency.  The 320x240-60 mode is
 * the initial AOI for the second and third planes.
 */
static struct fb_videomode fsl_diu_mode_db[] = {
	{
		.refresh	= 60,
		.xres		= 1024,
		.yres		= 768,
		.pixclock	= 15385,
		.left_margin	= 160,
		.right_margin	= 24,
		.upper_margin	= 29,
		.lower_margin	= 3,
		.hsync_len	= 136,
		.vsync_len	= 6,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 320,
		.yres		= 240,
		.pixclock	= 79440,
		.left_margin	= 16,
		.right_margin	= 16,
		.upper_margin	= 16,
		.lower_margin	= 5,
		.hsync_len	= 48,
		.vsync_len	= 1,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh        = 60,
		.xres           = 640,
		.yres           = 480,
		.pixclock       = 39722,
		.left_margin    = 48,
		.right_margin   = 16,
		.upper_margin   = 33,
		.lower_margin   = 10,
		.hsync_len      = 96,
		.vsync_len      = 2,
		.sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode          = FB_VMODE_NONINTERLACED
	},
	{
		.refresh        = 72,
		.xres           = 640,
		.yres           = 480,
		.pixclock       = 32052,
		.left_margin    = 128,
		.right_margin   = 24,
		.upper_margin   = 28,
		.lower_margin   = 9,
		.hsync_len      = 40,
		.vsync_len      = 3,
		.sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode          = FB_VMODE_NONINTERLACED
	},
	{
		.refresh        = 75,
		.xres           = 640,
		.yres           = 480,
		.pixclock       = 31747,
		.left_margin    = 120,
		.right_margin   = 16,
		.upper_margin   = 16,
		.lower_margin   = 1,
		.hsync_len      = 64,
		.vsync_len      = 3,
		.sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode          = FB_VMODE_NONINTERLACED
	},
	{
		.refresh        = 90,
		.xres           = 640,
		.yres           = 480,
		.pixclock       = 25057,
		.left_margin    = 120,
		.right_margin   = 32,
		.upper_margin   = 14,
		.lower_margin   = 25,
		.hsync_len      = 40,
		.vsync_len      = 14,
		.sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode          = FB_VMODE_NONINTERLACED
	},
	{
		.refresh        = 100,
		.xres           = 640,
		.yres           = 480,
		.pixclock       = 22272,
		.left_margin    = 48,
		.right_margin   = 32,
		.upper_margin   = 17,
		.lower_margin   = 22,
		.hsync_len      = 128,
		.vsync_len      = 12,
		.sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode          = FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 800,
		.yres		= 480,
		.pixclock	= 33805,
		.left_margin	= 96,
		.right_margin	= 24,
		.upper_margin	= 10,
		.lower_margin	= 3,
		.hsync_len	= 72,
		.vsync_len	= 7,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh        = 60,
		.xres           = 800,
		.yres           = 600,
		.pixclock       = 25000,
		.left_margin    = 88,
		.right_margin   = 40,
		.upper_margin   = 23,
		.lower_margin   = 1,
		.hsync_len      = 128,
		.vsync_len      = 4,
		.sync           = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode          = FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 854,
		.yres		= 480,
		.pixclock	= 31518,
		.left_margin	= 104,
		.right_margin	= 16,
		.upper_margin	= 13,
		.lower_margin	= 1,
		.hsync_len	= 88,
		.vsync_len	= 3,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 70,
		.xres		= 1024,
		.yres		= 768,
		.pixclock	= 16886,
		.left_margin	= 3,
		.right_margin	= 3,
		.upper_margin	= 2,
		.lower_margin	= 2,
		.hsync_len	= 40,
		.vsync_len	= 18,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 75,
		.xres		= 1024,
		.yres		= 768,
		.pixclock	= 15009,
		.left_margin	= 3,
		.right_margin	= 3,
		.upper_margin	= 2,
		.lower_margin	= 2,
		.hsync_len	= 80,
		.vsync_len	= 32,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 1280,
		.yres		= 480,
		.pixclock	= 18939,
		.left_margin	= 353,
		.right_margin	= 47,
		.upper_margin	= 39,
		.lower_margin	= 4,
		.hsync_len	= 8,
		.vsync_len	= 2,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 1280,
		.yres		= 720,
		.pixclock	= 13426,
		.left_margin	= 192,
		.right_margin	= 64,
		.upper_margin	= 22,
		.lower_margin	= 1,
		.hsync_len	= 136,
		.vsync_len	= 3,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 1280,
		.yres		= 1024,
		.pixclock	= 9375,
		.left_margin	= 38,
		.right_margin	= 128,
		.upper_margin	= 2,
		.lower_margin	= 7,
		.hsync_len	= 216,
		.vsync_len	= 37,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 70,
		.xres		= 1280,
		.yres		= 1024,
		.pixclock	= 9380,
		.left_margin	= 6,
		.right_margin	= 6,
		.upper_margin	= 4,
		.lower_margin	= 4,
		.hsync_len	= 60,
		.vsync_len	= 94,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 75,
		.xres		= 1280,
		.yres		= 1024,
		.pixclock	= 9380,
		.left_margin	= 6,
		.right_margin	= 6,
		.upper_margin	= 4,
		.lower_margin	= 4,
		.hsync_len	= 60,
		.vsync_len	= 15,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
	{
		.refresh	= 60,
		.xres		= 1920,
		.yres		= 1080,
		.pixclock	= 5787,
		.left_margin	= 328,
		.right_margin	= 120,
		.upper_margin	= 34,
		.lower_margin	= 1,
		.hsync_len	= 208,
		.vsync_len	= 3,
		.sync		= FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
		.vmode		= FB_VMODE_NONINTERLACED
	},
};

static char *fb_mode;
static unsigned long default_bpp = 32;
static enum fsl_diu_monitor_port monitor_port;
static char *monitor_string;

#if defined(CONFIG_NOT_COHERENT_CACHE)
static u8 *coherence_data;
static size_t coherence_data_size;
static unsigned int d_cache_line_size;
#endif

static DEFINE_SPINLOCK(diu_lock);

enum mfb_index {
	PLANE0 = 0,	/* Plane 0, only one AOI that fills the screen */
	PLANE1_AOI0,	/* Plane 1, first AOI */
	PLANE1_AOI1,	/* Plane 1, second AOI */
	PLANE2_AOI0,	/* Plane 2, first AOI */
	PLANE2_AOI1,	/* Plane 2, second AOI */
};

struct mfb_info {
	enum mfb_index index;
	char *id;
	int registered;
	unsigned long pseudo_palette[16];
	struct diu_ad *ad;
	unsigned char g_alpha;
	unsigned int count;
	int x_aoi_d;		/* aoi display x offset to physical screen */
	int y_aoi_d;		/* aoi display y offset to physical screen */
	struct fsl_diu_data *parent;
};

/**
 * struct fsl_diu_data - per-DIU data structure
 * @dma_addr: DMA address of this structure
 * @fsl_diu_info: fb_info objects, one per AOI
 * @dev_attr: sysfs structure
 * @irq: IRQ
 * @monitor_port: the monitor port this DIU is connected to
 * @diu_reg: pointer to the DIU hardware registers
 * @reg_lock: spinlock for register access
 * @dummy_aoi: video buffer for the 4x4 32-bit dummy AOI
 * dummy_ad: DIU Area Descriptor for the dummy AOI
 * @ad[]: Area Descriptors for each real AOI
 * @gamma: gamma color table
 * @cursor: hardware cursor data
 *
 * This data structure must be allocated with 32-byte alignment, so that the
 * internal fields can be aligned properly.
 */
struct fsl_diu_data {
	dma_addr_t dma_addr;
	struct fb_info fsl_diu_info[NUM_AOIS];
	struct mfb_info mfb[NUM_AOIS];
	struct device_attribute dev_attr;
	unsigned int irq;
	enum fsl_diu_monitor_port monitor_port;
	struct diu __iomem *diu_reg;
	spinlock_t reg_lock;
	u8 dummy_aoi[4 * 4 * 4];
	struct diu_ad dummy_ad __aligned(8);
	struct diu_ad ad[NUM_AOIS] __aligned(8);
	u8 gamma[256 * 3] __aligned(32);
	/* It's easier to parse the cursor data as little-endian */
	__le16 cursor[MAX_CURS * MAX_CURS] __aligned(32);
	/* Blank cursor data -- used to hide the cursor */
	__le16 blank_cursor[MAX_CURS * MAX_CURS] __aligned(32);
	uint8_t edid_data[EDID_LENGTH];
	bool has_edid;
} __aligned(32);

/* Determine the DMA address of a member of the fsl_diu_data structure */
#define DMA_ADDR(p, f) ((p)->dma_addr + offsetof(struct fsl_diu_data, f))

static const struct mfb_info mfb_template[] = {
	{
		.index = PLANE0,
		.id = "Panel0",
		.registered = 0,
		.count = 0,
		.x_aoi_d = 0,
		.y_aoi_d = 0,
	},
	{
		.index = PLANE1_AOI0,
		.id = "Panel1 AOI0",
		.registered = 0,
		.g_alpha = 0xff,
		.count = 0,
		.x_aoi_d = 0,
		.y_aoi_d = 0,
	},
	{
		.index = PLANE1_AOI1,
		.id = "Panel1 AOI1",
		.registered = 0,
		.g_alpha = 0xff,
		.count = 0,
		.x_aoi_d = 0,
		.y_aoi_d = 480,
	},
	{
		.index = PLANE2_AOI0,
		.id = "Panel2 AOI0",
		.registered = 0,
		.g_alpha = 0xff,
		.count = 0,
		.x_aoi_d = 640,
		.y_aoi_d = 0,
	},
	{
		.index = PLANE2_AOI1,
		.id = "Panel2 AOI1",
		.registered = 0,
		.g_alpha = 0xff,
		.count = 0,
		.x_aoi_d = 640,
		.y_aoi_d = 480,
	},
};

#ifdef DEBUG
static void __attribute__ ((unused)) fsl_diu_dump(struct diu __iomem *hw)
{
	mb();
	pr_debug("DIU: desc=%08x,%08x,%08x, gamma=%08x palette=%08x "
		 "cursor=%08x curs_pos=%08x diu_mode=%08x bgnd=%08x "
		 "disp_size=%08x hsyn_para=%08x vsyn_para=%08x syn_pol=%08x "
		 "thresholds=%08x int_mask=%08x plut=%08x\n",
		 hw->desc[0], hw->desc[1], hw->desc[2], hw->gamma,
		 hw->palette, hw->cursor, hw->curs_pos, hw->diu_mode,
		 hw->bgnd, hw->disp_size, hw->hsyn_para, hw->vsyn_para,
		 hw->syn_pol, hw->thresholds, hw->int_mask, hw->plut);
	rmb();
}
#endif

/**
 * fsl_diu_name_to_port - convert a port name to a monitor port enum
 *
 * Takes the name of a monitor port ("dvi", "lvds", or "dlvds") and returns
 * the enum fsl_diu_monitor_port that corresponds to that string.
 *
 * For compatibility with older versions, a number ("0", "1", or "2") is also
 * supported.
 *
 * If the string is unknown, DVI is assumed.
 *
 * If the particular port is not supported by the platform, another port
 * (platform-specific) is chosen instead.
 */
static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
{
	enum fsl_diu_monitor_port port = FSL_DIU_PORT_DVI;
	unsigned long val;

	if (s) {
		if (!kstrtoul(s, 10, &val) && (val <= 2))
			port = (enum fsl_diu_monitor_port) val;
		else if (strncmp(s, "lvds", 4) == 0)
			port = FSL_DIU_PORT_LVDS;
		else if (strncmp(s, "dlvds", 5) == 0)
			port = FSL_DIU_PORT_DLVDS;
	}

	if (diu_ops.valid_monitor_port)
		port = diu_ops.valid_monitor_port(port);

	return port;
}

/*
 * Workaround for failed writing desc register of planes.
 * Needed with MPC5121 DIU rev 2.0 silicon.
 */
void wr_reg_wa(u32 *reg, u32 val)
{
	do {
		out_be32(reg, val);
	} while (in_be32(reg) != val);
}

static void fsl_diu_enable_panel(struct fb_info *info)
{
	struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
	struct diu_ad *ad = mfbi->ad;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu __iomem *hw = data->diu_reg;

	switch (mfbi->index) {
	case PLANE0:
		wr_reg_wa(&hw->desc[0], ad->paddr);
		break;
	case PLANE1_AOI0:
		cmfbi = &data->mfb[2];
		if (hw->desc[1] != ad->paddr) {	/* AOI0 closed */
			if (cmfbi->count > 0)	/* AOI1 open */
				ad->next_ad =
					cpu_to_le32(cmfbi->ad->paddr);
			else
				ad->next_ad = 0;
			wr_reg_wa(&hw->desc[1], ad->paddr);
		}
		break;
	case PLANE2_AOI0:
		cmfbi = &data->mfb[4];
		if (hw->desc[2] != ad->paddr) {	/* AOI0 closed */
			if (cmfbi->count > 0)	/* AOI1 open */
				ad->next_ad =
					cpu_to_le32(cmfbi->ad->paddr);
			else
				ad->next_ad = 0;
			wr_reg_wa(&hw->desc[2], ad->paddr);
		}
		break;
	case PLANE1_AOI1:
		pmfbi = &data->mfb[1];
		ad->next_ad = 0;
		if (hw->desc[1] == data->dummy_ad.paddr)
			wr_reg_wa(&hw->desc[1], ad->paddr);
		else					/* AOI0 open */
			pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
		break;
	case PLANE2_AOI1:
		pmfbi = &data->mfb[3];
		ad->next_ad = 0;
		if (hw->desc[2] == data->dummy_ad.paddr)
			wr_reg_wa(&hw->desc[2], ad->paddr);
		else				/* AOI0 was open */
			pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
		break;
	}
}

static void fsl_diu_disable_panel(struct fb_info *info)
{
	struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
	struct diu_ad *ad = mfbi->ad;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu __iomem *hw = data->diu_reg;

	switch (mfbi->index) {
	case PLANE0:
		wr_reg_wa(&hw->desc[0], 0);
		break;
	case PLANE1_AOI0:
		cmfbi = &data->mfb[2];
		if (cmfbi->count > 0)	/* AOI1 is open */
			wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr);
					/* move AOI1 to the first */
		else			/* AOI1 was closed */
			wr_reg_wa(&hw->desc[1], data->dummy_ad.paddr);
					/* close AOI 0 */
		break;
	case PLANE2_AOI0:
		cmfbi = &data->mfb[4];
		if (cmfbi->count > 0)	/* AOI1 is open */
			wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr);
					/* move AOI1 to the first */
		else			/* AOI1 was closed */
			wr_reg_wa(&hw->desc[2], data->dummy_ad.paddr);
					/* close AOI 0 */
		break;
	case PLANE1_AOI1:
		pmfbi = &data->mfb[1];
		if (hw->desc[1] != ad->paddr) {
				/* AOI1 is not the first in the chain */
			if (pmfbi->count > 0)
					/* AOI0 is open, must be the first */
				pmfbi->ad->next_ad = 0;
		} else			/* AOI1 is the first in the chain */
			wr_reg_wa(&hw->desc[1], data->dummy_ad.paddr);
					/* close AOI 1 */
		break;
	case PLANE2_AOI1:
		pmfbi = &data->mfb[3];
		if (hw->desc[2] != ad->paddr) {
				/* AOI1 is not the first in the chain */
			if (pmfbi->count > 0)
				/* AOI0 is open, must be the first */
				pmfbi->ad->next_ad = 0;
		} else		/* AOI1 is the first in the chain */
			wr_reg_wa(&hw->desc[2], data->dummy_ad.paddr);
				/* close AOI 1 */
		break;
	}
}

static void enable_lcdc(struct fb_info *info)
{
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu __iomem *hw = data->diu_reg;

	out_be32(&hw->diu_mode, MFB_MODE1);
}

static void disable_lcdc(struct fb_info *info)
{
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu __iomem *hw = data->diu_reg;

	out_be32(&hw->diu_mode, 0);
}

static void adjust_aoi_size_position(struct fb_var_screeninfo *var,
				struct fb_info *info)
{
	struct mfb_info *lower_aoi_mfbi, *upper_aoi_mfbi, *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	int available_height, upper_aoi_bottom;
	enum mfb_index index = mfbi->index;
	int lower_aoi_is_open, upper_aoi_is_open;
	__u32 base_plane_width, base_plane_height, upper_aoi_height;

	base_plane_width = data->fsl_diu_info[0].var.xres;
	base_plane_height = data->fsl_diu_info[0].var.yres;

	if (mfbi->x_aoi_d < 0)
		mfbi->x_aoi_d = 0;
	if (mfbi->y_aoi_d < 0)
		mfbi->y_aoi_d = 0;
	switch (index) {
	case PLANE0:
		if (mfbi->x_aoi_d != 0)
			mfbi->x_aoi_d = 0;
		if (mfbi->y_aoi_d != 0)
			mfbi->y_aoi_d = 0;
		break;
	case PLANE1_AOI0:
	case PLANE2_AOI0:
		lower_aoi_mfbi = data->fsl_diu_info[index+1].par;
		lower_aoi_is_open = lower_aoi_mfbi->count > 0 ? 1 : 0;
		if (var->xres > base_plane_width)
			var->xres = base_plane_width;
		if ((mfbi->x_aoi_d + var->xres) > base_plane_width)
			mfbi->x_aoi_d = base_plane_width - var->xres;

		if (lower_aoi_is_open)
			available_height = lower_aoi_mfbi->y_aoi_d;
		else
			available_height = base_plane_height;
		if (var->yres > available_height)
			var->yres = available_height;
		if ((mfbi->y_aoi_d + var->yres) > available_height)
			mfbi->y_aoi_d = available_height - var->yres;
		break;
	case PLANE1_AOI1:
	case PLANE2_AOI1:
		upper_aoi_mfbi = data->fsl_diu_info[index-1].par;
		upper_aoi_height = data->fsl_diu_info[index-1].var.yres;
		upper_aoi_bottom = upper_aoi_mfbi->y_aoi_d + upper_aoi_height;
		upper_aoi_is_open = upper_aoi_mfbi->count > 0 ? 1 : 0;
		if (var->xres > base_plane_width)
			var->xres = base_plane_width;
		if ((mfbi->x_aoi_d + var->xres) > base_plane_width)
			mfbi->x_aoi_d = base_plane_width - var->xres;
		if (mfbi->y_aoi_d < 0)
			mfbi->y_aoi_d = 0;
		if (upper_aoi_is_open) {
			if (mfbi->y_aoi_d < upper_aoi_bottom)
				mfbi->y_aoi_d = upper_aoi_bottom;
			available_height = base_plane_height
						- upper_aoi_bottom;
		} else
			available_height = base_plane_height;
		if (var->yres > available_height)
			var->yres = available_height;
		if ((mfbi->y_aoi_d + var->yres) > base_plane_height)
			mfbi->y_aoi_d = base_plane_height - var->yres;
		break;
	}
}
/*
 * Checks to see if the hardware supports the state requested by var passed
 * in. This function does not alter the hardware state! If the var passed in
 * is slightly off by what the hardware can support then we alter the var
 * PASSED in to what we can do. If the hardware doesn't support mode change
 * a -EINVAL will be returned by the upper layers.
 */
static int fsl_diu_check_var(struct fb_var_screeninfo *var,
				struct fb_info *info)
{
	if (var->xres_virtual < var->xres)
		var->xres_virtual = var->xres;
	if (var->yres_virtual < var->yres)
		var->yres_virtual = var->yres;

	if (var->xoffset + info->var.xres > info->var.xres_virtual)
		var->xoffset = info->var.xres_virtual - info->var.xres;

	if (var->yoffset + info->var.yres > info->var.yres_virtual)
		var->yoffset = info->var.yres_virtual - info->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 = 0;
		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 = 16;
		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;
	}

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

	/* Copy nonstd field to/from sync for fbset usage */
	var->sync |= var->nonstd;
	var->nonstd |= var->sync;

	adjust_aoi_size_position(var, info);
	return 0;
}

static void set_fix(struct fb_info *info)
{
	struct fb_fix_screeninfo *fix = &info->fix;
	struct fb_var_screeninfo *var = &info->var;
	struct mfb_info *mfbi = info->par;

	strncpy(fix->id, mfbi->id, sizeof(fix->id));
	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;
}

static void update_lcdc(struct fb_info *info)
{
	struct fb_var_screeninfo *var = &info->var;
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu __iomem *hw;
	int i, j;
	u8 *gamma_table_base;

	u32 temp;

	hw = data->diu_reg;

	if (diu_ops.set_monitor_port)
		diu_ops.set_monitor_port(data->monitor_port);
	gamma_table_base = data->gamma;

	/* Prep for DIU init  - gamma table, cursor table */

	for (i = 0; i <= 2; i++)
		for (j = 0; j <= 255; j++)
			*gamma_table_base++ = j;

	if (diu_ops.set_gamma_table)
		diu_ops.set_gamma_table(data->monitor_port, data->gamma);

	disable_lcdc(info);

	/* Program DIU registers */

	out_be32(&hw->gamma, DMA_ADDR(data, gamma));

	out_be32(&hw->bgnd, 0x007F7F7F); /* Set background to grey */
	out_be32(&hw->disp_size, (var->yres << 16) | var->xres);

	/* Horizontal and vertical configuration register */
	temp = var->left_margin << 22 | /* BP_H */
	       var->hsync_len << 11 |   /* PW_H */
	       var->right_margin;       /* FP_H */

	out_be32(&hw->hsyn_para, temp);

	temp = var->upper_margin << 22 | /* BP_V */
	       var->vsync_len << 11 |    /* PW_V  */
	       var->lower_margin;        /* FP_V  */

	out_be32(&hw->vsyn_para, temp);

	diu_ops.set_pixel_clock(var->pixclock);

#ifndef CONFIG_PPC_MPC512x
	/*
	 * The PLUT register is defined differently on the MPC5121 than it
	 * is on other SOCs.  Unfortunately, there's no documentation that
	 * explains how it's supposed to be programmed, so for now, we leave
	 * it at the default value on the MPC5121.
	 *
	 * For other SOCs, program it for the highest priority, which will
	 * reduce the chance of underrun. Technically, we should scale the
	 * priority to match the screen resolution, but doing that properly
	 * requires delicate fine-tuning for each use-case.
	 */
	out_be32(&hw->plut, 0x01F5F666);
#endif

	/* Enable the DIU */
	enable_lcdc(info);
}

static int map_video_memory(struct fb_info *info)
{
	u32 smem_len = info->fix.line_length * info->var.yres_virtual;
	void *p;

	p = alloc_pages_exact(smem_len, GFP_DMA | __GFP_ZERO);
	if (!p) {
		dev_err(info->dev, "unable to allocate fb memory\n");
		return -ENOMEM;
	}
	mutex_lock(&info->mm_lock);
	info->screen_base = p;
	info->fix.smem_start = virt_to_phys(info->screen_base);
	info->fix.smem_len = smem_len;
	mutex_unlock(&info->mm_lock);
	info->screen_size = info->fix.smem_len;

	return 0;
}

static void unmap_video_memory(struct fb_info *info)
{
	void *p = info->screen_base;
	size_t l = info->fix.smem_len;

	mutex_lock(&info->mm_lock);
	info->screen_base = NULL;
	info->fix.smem_start = 0;
	info->fix.smem_len = 0;
	mutex_unlock(&info->mm_lock);

	if (p)
		free_pages_exact(p, l);
}

/*
 * Using the fb_var_screeninfo in fb_info we set the aoi of this
 * particular framebuffer. It is a light version of fsl_diu_set_par.
 */
static int fsl_diu_set_aoi(struct fb_info *info)
{
	struct fb_var_screeninfo *var = &info->var;
	struct mfb_info *mfbi = info->par;
	struct diu_ad *ad = mfbi->ad;

	/* AOI should not be greater than display size */
	ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset);
	ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d);
	return 0;
}

/**
 * fsl_diu_get_pixel_format: return the pixel format for a given color depth
 *
 * The pixel format is a 32-bit value that determine which bits in each
 * pixel are to be used for each color.  This is the default function used
 * if the platform does not define its own version.
 */
static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
{
#define PF_BYTE_F		0x10000000
#define PF_ALPHA_C_MASK		0x0E000000
#define PF_ALPHA_C_SHIFT	25
#define PF_BLUE_C_MASK		0x01800000
#define PF_BLUE_C_SHIFT		23
#define PF_GREEN_C_MASK		0x00600000
#define PF_GREEN_C_SHIFT	21
#define PF_RED_C_MASK		0x00180000
#define PF_RED_C_SHIFT		19
#define PF_PALETTE		0x00040000
#define PF_PIXEL_S_MASK		0x00030000
#define PF_PIXEL_S_SHIFT	16
#define PF_COMP_3_MASK		0x0000F000
#define PF_COMP_3_SHIFT		12
#define PF_COMP_2_MASK		0x00000F00
#define PF_COMP_2_SHIFT		8
#define PF_COMP_1_MASK		0x000000F0
#define PF_COMP_1_SHIFT		4
#define PF_COMP_0_MASK		0x0000000F
#define PF_COMP_0_SHIFT		0

#define MAKE_PF(alpha, red, green, blue, size, c0, c1, c2, c3) \
	cpu_to_le32(PF_BYTE_F | (alpha << PF_ALPHA_C_SHIFT) | \
	(blue << PF_BLUE_C_SHIFT) | (green << PF_GREEN_C_SHIFT) | \
	(red << PF_RED_C_SHIFT) | (c3 << PF_COMP_3_SHIFT) | \
	(c2 << PF_COMP_2_SHIFT) | (c1 << PF_COMP_1_SHIFT) | \
	(c0 << PF_COMP_0_SHIFT) | (size << PF_PIXEL_S_SHIFT))

	switch (bits_per_pixel) {
	case 32:
		/* 0x88883316 */
		return MAKE_PF(3, 2, 1, 0, 3, 8, 8, 8, 8);
	case 24:
		/* 0x88082219 */
		return MAKE_PF(4, 0, 1, 2, 2, 8, 8, 8, 0);
	case 16:
		/* 0x65053118 */
		return MAKE_PF(4, 2, 1, 0, 1, 5, 6, 5, 0);
	default:
		pr_err("fsl-diu: unsupported color depth %u\n", bits_per_pixel);
		return 0;
	}
}

/*
 * Copies a cursor image from user space to the proper place in driver
 * memory so that the hardware can display the cursor image.
 *
 * Cursor data is represented as a sequence of 'width' bits packed into bytes.
 * That is, the first 8 bits are in the first byte, the second 8 bits in the
 * second byte, and so on.  Therefore, the each row of the cursor is (width +
 * 7) / 8 bytes of 'data'
 *
 * The DIU only supports cursors up to 32x32 (MAX_CURS).  We reject cursors
 * larger than this, so we already know that 'width' <= 32.  Therefore, we can
 * simplify our code by using a 32-bit big-endian integer ("line") to read in
 * a single line of pixels, and only look at the top 'width' bits of that
 * integer.
 *
 * This could result in an unaligned 32-bit read.  For example, if the cursor
 * is 24x24, then the first three bytes of 'image' contain the pixel data for
 * the top line of the cursor.  We do a 32-bit read of 'image', but we look
 * only at the top 24 bits.  Then we increment 'image' by 3 bytes.  The next
 * read is unaligned.  The only problem is that we might read past the end of
 * 'image' by 1-3 bytes, but that should not cause any problems.
 */
static void fsl_diu_load_cursor_image(struct fb_info *info,
	const void *image, uint16_t bg, uint16_t fg,
	unsigned int width, unsigned int height)
{
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	__le16 *cursor = data->cursor;
	__le16 _fg = cpu_to_le16(fg);
	__le16 _bg = cpu_to_le16(bg);
	unsigned int h, w;

	for (h = 0; h < height; h++) {
		uint32_t mask = 1 << 31;
		uint32_t line = be32_to_cpup(image);

		for (w = 0; w < width; w++) {
			cursor[w] = (line & mask) ? _fg : _bg;
			mask >>= 1;
		}

		cursor += MAX_CURS;
		image += DIV_ROUND_UP(width, 8);
	}
}

/*
 * Set a hardware cursor.  The image data for the cursor is passed via the
 * fb_cursor object.
 */
static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu __iomem *hw = data->diu_reg;

	if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)
		return -EINVAL;

	/* The cursor size has changed */
	if (cursor->set & FB_CUR_SETSIZE) {
		/*
		 * The DIU cursor is a fixed size, so when we get this
		 * message, instead of resizing the cursor, we just clear
		 * all the image data, in expectation of new data.  However,
		 * in tests this control does not appear to be normally
		 * called.
		 */
		memset(data->cursor, 0, sizeof(data->cursor));
	}

	/* The cursor position has changed (cursor->image.dx|dy) */
	if (cursor->set & FB_CUR_SETPOS) {
		uint32_t xx, yy;

		yy = (cursor->image.dy - info->var.yoffset) & 0x7ff;
		xx = (cursor->image.dx - info->var.xoffset) & 0x7ff;

		out_be32(&hw->curs_pos, yy << 16 | xx);
	}

	/*
	 * FB_CUR_SETIMAGE - the cursor image has changed
	 * FB_CUR_SETCMAP  - the cursor colors has changed
	 * FB_CUR_SETSHAPE - the cursor bitmask has changed
	 */
	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {
		unsigned int image_size =
			DIV_ROUND_UP(cursor->image.width, 8) * cursor->image.height;
		unsigned int image_words =
			DIV_ROUND_UP(image_size, sizeof(uint32_t));
		unsigned int bg_idx = cursor->image.bg_color;
		unsigned int fg_idx = cursor->image.fg_color;
		uint8_t buffer[image_size];
		uint32_t *image, *source, *mask;
		uint16_t fg, bg;
		unsigned int i;

		if (info->state != FBINFO_STATE_RUNNING)
			return 0;

		/*
		 * Determine the size of the cursor image data.  Normally,
		 * it's 8x16.
		 */
		image_size = DIV_ROUND_UP(cursor->image.width, 8) *
			cursor->image.height;

		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3) |
		     1 << 15;

		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
		     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
		     ((info->cmap.blue[fg_idx] & 0xf8) >> 3) |
		     1 << 15;

		/* Use 32-bit operations on the data to improve performance */
		image = (uint32_t *)buffer;
		source = (uint32_t *)cursor->image.data;
		mask = (uint32_t *)cursor->mask;

		if (cursor->rop == ROP_XOR)
			for (i = 0; i < image_words; i++)
				image[i] = source[i] ^ mask[i];
		else
			for (i = 0; i < image_words; i++)
				image[i] = source[i] & mask[i];

		fsl_diu_load_cursor_image(info, image, bg, fg,
			cursor->image.width, cursor->image.height);
	}

	/*
	 * Show or hide the cursor.  The cursor data is always stored in the
	 * 'cursor' memory block, and the actual cursor position is always in
	 * the DIU's CURS_POS register.  To hide the cursor, we redirect the
	 * CURSOR register to a blank cursor.  The show the cursor, we
	 * redirect the CURSOR register to the real cursor data.
	 */
	if (cursor->enable)
		out_be32(&hw->cursor, DMA_ADDR(data, cursor));
	else
		out_be32(&hw->cursor, DMA_ADDR(data, blank_cursor));

	return 0;
}

/*
 * Using the fb_var_screeninfo in fb_info we set the resolution of this
 * particular framebuffer. This function alters the fb_fix_screeninfo stored
 * in fb_info. It does not alter var in fb_info since we are using that
 * data. This means we depend on the data in var inside fb_info to be
 * supported by the hardware. fsl_diu_check_var is always called before
 * fsl_diu_set_par to ensure this.
 */
static int fsl_diu_set_par(struct fb_info *info)
{
	unsigned long len;
	struct fb_var_screeninfo *var = &info->var;
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	struct diu_ad *ad = mfbi->ad;
	struct diu __iomem *hw;

	hw = data->diu_reg;

	set_fix(info);

	len = info->var.yres_virtual * info->fix.line_length;
	/* Alloc & dealloc each time resolution/bpp change */
	if (len != info->fix.smem_len) {
		if (info->fix.smem_start)
			unmap_video_memory(info);

		/* Memory allocation for framebuffer */
		if (map_video_memory(info)) {
			dev_err(info->dev, "unable to allocate fb memory 1\n");
			return -ENOMEM;
		}
	}

	if (diu_ops.get_pixel_format)
		ad->pix_fmt = diu_ops.get_pixel_format(data->monitor_port,
						       var->bits_per_pixel);
	else
		ad->pix_fmt = fsl_diu_get_pixel_format(var->bits_per_pixel);

	ad->addr    = cpu_to_le32(info->fix.smem_start);
	ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
				var->xres_virtual) | mfbi->g_alpha;
	/* AOI should not be greater than display size */
	ad->aoi_size 	= cpu_to_le32((var->yres << 16) | var->xres);
	ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset);
	ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d);

	/* Disable chroma keying function */
	ad->ckmax_r = 0;
	ad->ckmax_g = 0;
	ad->ckmax_b = 0;

	ad->ckmin_r = 255;
	ad->ckmin_g = 255;
	ad->ckmin_b = 255;

	if (mfbi->index == PLANE0)
		update_lcdc(info);
	return 0;
}

static inline __u32 CNVT_TOHW(__u32 val, __u32 width)
{
	return ((val << width) + 0x7FFF - val) >> 16;
}

/*
 * Set a single color register. The values supplied have a 16 bit magnitude
 * which needs to be scaled in this function for the hardware. Things to take
 * into consideration are how many color registers, if any, are supported with
 * the current color visual. With truecolor mode no color palettes are
 * supported. Here a pseudo palette is created which we store the value in
 * pseudo_palette in struct fb_info. For pseudocolor mode we have a limited
 * color palette.
 */
static int fsl_diu_setcolreg(unsigned int regno, unsigned int red,
			     unsigned int green, unsigned int blue,
			     unsigned int transp, struct fb_info *info)
{
	int ret = 1;

	/*
	 * If greyscale is true, then we convert the RGB value
	 * to greyscale no matter what visual we are using.
	 */
	if (info->var.grayscale)
		red = green = blue = (19595 * red + 38470 * green +
				      7471 * blue) >> 16;
	switch (info->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 = info->pseudo_palette;
			u32 v;

			red = CNVT_TOHW(red, info->var.red.length);
			green = CNVT_TOHW(green, info->var.green.length);
			blue = CNVT_TOHW(blue, info->var.blue.length);
			transp = CNVT_TOHW(transp, info->var.transp.length);

			v = (red << info->var.red.offset) |
			    (green << info->var.green.offset) |
			    (blue << info->var.blue.offset) |
			    (transp << info->var.transp.offset);

			pal[regno] = v;
			ret = 0;
		}
		break;
	}

	return ret;
}

/*
 * Pan (or wrap, depending on the `vmode' field) the display using the
 * 'xoffset' and 'yoffset' fields of the 'var' structure. If the values
 * don't fit, return -EINVAL.
 */
static int fsl_diu_pan_display(struct fb_var_screeninfo *var,
			     struct fb_info *info)
{
	if ((info->var.xoffset == var->xoffset) &&
	    (info->var.yoffset == var->yoffset))
		return 0;	/* No change, do nothing */

	if (var->xoffset + info->var.xres > info->var.xres_virtual
	    || var->yoffset + info->var.yres > info->var.yres_virtual)
		return -EINVAL;

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

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

	fsl_diu_set_aoi(info);

	return 0;
}

static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd,
		       unsigned long arg)
{
	struct mfb_info *mfbi = info->par;
	struct diu_ad *ad = mfbi->ad;
	struct mfb_chroma_key ck;
	unsigned char global_alpha;
	struct aoi_display_offset aoi_d;
	__u32 pix_fmt;
	void __user *buf = (void __user *)arg;

	if (!arg)
		return -EINVAL;

	dev_dbg(info->dev, "ioctl %08x (dir=%s%s type=%u nr=%u size=%u)\n", cmd,
		_IOC_DIR(cmd) & _IOC_READ ? "R" : "",
		_IOC_DIR(cmd) & _IOC_WRITE ? "W" : "",
		_IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));

	switch (cmd) {
	case MFB_SET_PIXFMT_OLD:
		dev_warn(info->dev,
			 "MFB_SET_PIXFMT value of 0x%08x is deprecated.\n",
			 MFB_SET_PIXFMT_OLD);
	case MFB_SET_PIXFMT:
		if (copy_from_user(&pix_fmt, buf, sizeof(pix_fmt)))
			return -EFAULT;
		ad->pix_fmt = pix_fmt;
		break;
	case MFB_GET_PIXFMT_OLD:
		dev_warn(info->dev,
			 "MFB_GET_PIXFMT value of 0x%08x is deprecated.\n",
			 MFB_GET_PIXFMT_OLD);
	case MFB_GET_PIXFMT:
		pix_fmt = ad->pix_fmt;
		if (copy_to_user(buf, &pix_fmt, sizeof(pix_fmt)))
			return -EFAULT;
		break;
	case MFB_SET_AOID:
		if (copy_from_user(&aoi_d, buf, sizeof(aoi_d)))
			return -EFAULT;
		mfbi->x_aoi_d = aoi_d.x_aoi_d;
		mfbi->y_aoi_d = aoi_d.y_aoi_d;
		fsl_diu_check_var(&info->var, info);
		fsl_diu_set_aoi(info);
		break;
	case MFB_GET_AOID:
		aoi_d.x_aoi_d = mfbi->x_aoi_d;
		aoi_d.y_aoi_d = mfbi->y_aoi_d;
		if (copy_to_user(buf, &aoi_d, sizeof(aoi_d)))
			return -EFAULT;
		break;
	case MFB_GET_ALPHA:
		global_alpha = mfbi->g_alpha;
		if (copy_to_user(buf, &global_alpha, sizeof(global_alpha)))
			return -EFAULT;
		break;
	case MFB_SET_ALPHA:
		/* set panel information */
		if (copy_from_user(&global_alpha, buf, sizeof(global_alpha)))
			return -EFAULT;
		ad->src_size_g_alpha = (ad->src_size_g_alpha & (~0xff)) |
							(global_alpha & 0xff);
		mfbi->g_alpha = global_alpha;
		break;
	case MFB_SET_CHROMA_KEY:
		/* set panel winformation */
		if (copy_from_user(&ck, buf, sizeof(ck)))
			return -EFAULT;

		if (ck.enable &&
		   (ck.red_max < ck.red_min ||
		    ck.green_max < ck.green_min ||
		    ck.blue_max < ck.blue_min))
			return -EINVAL;

		if (!ck.enable) {
			ad->ckmax_r = 0;
			ad->ckmax_g = 0;
			ad->ckmax_b = 0;
			ad->ckmin_r = 255;
			ad->ckmin_g = 255;
			ad->ckmin_b = 255;
		} else {
			ad->ckmax_r = ck.red_max;
			ad->ckmax_g = ck.green_max;
			ad->ckmax_b = ck.blue_max;
			ad->ckmin_r = ck.red_min;
			ad->ckmin_g = ck.green_min;
			ad->ckmin_b = ck.blue_min;
		}
		break;
#ifdef CONFIG_PPC_MPC512x
	case MFB_SET_GAMMA: {
		struct fsl_diu_data *data = mfbi->parent;

		if (copy_from_user(data->gamma, buf, sizeof(data->gamma)))
			return -EFAULT;
		setbits32(&data->diu_reg->gamma, 0); /* Force table reload */
		break;
	}
	case MFB_GET_GAMMA: {
		struct fsl_diu_data *data = mfbi->parent;

		if (copy_to_user(buf, data->gamma, sizeof(data->gamma)))
			return -EFAULT;
		break;
	}
#endif
	default:
		dev_err(info->dev, "unknown ioctl command (0x%08X)\n", cmd);
		return -ENOIOCTLCMD;
	}

	return 0;
}

static inline void fsl_diu_enable_interrupts(struct fsl_diu_data *data)
{
	u32 int_mask = INT_UNDRUN; /* enable underrun detection */

	if (IS_ENABLED(CONFIG_NOT_COHERENT_CACHE))
		int_mask |= INT_VSYNC; /* enable vertical sync */

	clrbits32(&data->diu_reg->int_mask, int_mask);
}

/* turn on fb if count == 1
 */
static int fsl_diu_open(struct fb_info *info, int user)
{
	struct mfb_info *mfbi = info->par;
	int res = 0;

	/* free boot splash memory on first /dev/fb0 open */
	if ((mfbi->index == PLANE0) && diu_ops.release_bootmem)
		diu_ops.release_bootmem();

	spin_lock(&diu_lock);
	mfbi->count++;
	if (mfbi->count == 1) {
		fsl_diu_check_var(&info->var, info);
		res = fsl_diu_set_par(info);
		if (res < 0)
			mfbi->count--;
		else {
			fsl_diu_enable_interrupts(mfbi->parent);
			fsl_diu_enable_panel(info);
		}
	}

	spin_unlock(&diu_lock);
	return res;
}

/* turn off fb if count == 0
 */
static int fsl_diu_release(struct fb_info *info, int user)
{
	struct mfb_info *mfbi = info->par;
	int res = 0;

	spin_lock(&diu_lock);
	mfbi->count--;
	if (mfbi->count == 0) {
		struct fsl_diu_data *data = mfbi->parent;
		bool disable = true;
		int i;

		/* Disable interrupts only if all AOIs are closed */
		for (i = 0; i < NUM_AOIS; i++) {
			struct mfb_info *mi = data->fsl_diu_info[i].par;

			if (mi->count)
				disable = false;
		}
		if (disable)
			out_be32(&data->diu_reg->int_mask, 0xffffffff);
		fsl_diu_disable_panel(info);
	}

	spin_unlock(&diu_lock);
	return res;
}

static struct fb_ops fsl_diu_ops = {
	.owner = THIS_MODULE,
	.fb_check_var = fsl_diu_check_var,
	.fb_set_par = fsl_diu_set_par,
	.fb_setcolreg = fsl_diu_setcolreg,
	.fb_pan_display = fsl_diu_pan_display,
	.fb_fillrect = cfb_fillrect,
	.fb_copyarea = cfb_copyarea,
	.fb_imageblit = cfb_imageblit,
	.fb_ioctl = fsl_diu_ioctl,
	.fb_open = fsl_diu_open,
	.fb_release = fsl_diu_release,
	.fb_cursor = fsl_diu_cursor,
};

static int install_fb(struct fb_info *info)
{
	int rc;
	struct mfb_info *mfbi = info->par;
	struct fsl_diu_data *data = mfbi->parent;
	const char *aoi_mode, *init_aoi_mode = "320x240";
	struct fb_videomode *db = fsl_diu_mode_db;
	unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
	int has_default_mode = 1;

	info->var.activate = FB_ACTIVATE_NOW;
	info->fbops = &fsl_diu_ops;
	info->flags = FBINFO_DEFAULT | FBINFO_VIRTFB | FBINFO_PARTIAL_PAN_OK |
		FBINFO_READS_FAST;
	info->pseudo_palette = mfbi->pseudo_palette;

	rc = fb_alloc_cmap(&info->cmap, 16, 0);
	if (rc)
		return rc;

	if (mfbi->index == PLANE0) {
		if (data->has_edid) {
			/* Now build modedb from EDID */
			fb_edid_to_monspecs(data->edid_data, &info->monspecs);
			fb_videomode_to_modelist(info->monspecs.modedb,
						 info->monspecs.modedb_len,
						 &info->modelist);
			db = info->monspecs.modedb;
			dbsize = info->monspecs.modedb_len;
		}
		aoi_mode = fb_mode;
	} else {
		aoi_mode = init_aoi_mode;
	}
	rc = fb_find_mode(&info->var, info, aoi_mode, db, dbsize, NULL,
			  default_bpp);
	if (!rc) {
		/*
		 * For plane 0 we continue and look into
		 * driver's internal modedb.
		 */
		if ((mfbi->index == PLANE0) && data->has_edid)
			has_default_mode = 0;
		else
			return -EINVAL;
	}

	if (!has_default_mode) {
		rc = fb_find_mode(&info->var, info, aoi_mode, fsl_diu_mode_db,
			ARRAY_SIZE(fsl_diu_mode_db), NULL, default_bpp);
		if (rc)
			has_default_mode = 1;
	}

	/* Still not found, use preferred mode from database if any */
	if (!has_default_mode && info->monspecs.modedb) {
		struct fb_monspecs *specs = &info->monspecs;
		struct fb_videomode *modedb = &specs->modedb[0];

		/*
		 * Get preferred timing. If not found,
		 * first mode in database will be used.
		 */
		if (specs->misc & FB_MISC_1ST_DETAIL) {
			int i;

			for (i = 0; i < specs->modedb_len; i++) {
				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
					modedb = &specs->modedb[i];
					break;
				}
			}
		}

		info->var.bits_per_pixel = default_bpp;
		fb_videomode_to_var(&info->var, modedb);
	}

	if (fsl_diu_check_var(&info->var, info)) {
		dev_err(info->dev, "fsl_diu_check_var failed\n");
		unmap_video_memory(info);
		fb_dealloc_cmap(&info->cmap);
		return -EINVAL;
	}

	if (register_framebuffer(info) < 0) {
		dev_err(info->dev, "register_framebuffer failed\n");
		unmap_video_memory(info);
		fb_dealloc_cmap(&info->cmap);
		return -EINVAL;
	}

	mfbi->registered = 1;
	dev_info(info->dev, "%s registered successfully\n", mfbi->id);

	return 0;
}

static void uninstall_fb(struct fb_info *info)
{
	struct mfb_info *mfbi = info->par;

	if (!mfbi->registered)
		return;

	unregister_framebuffer(info);
	unmap_video_memory(info);
	if (&info->cmap)
		fb_dealloc_cmap(&info->cmap);

	mfbi->registered = 0;
}

static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
{
	struct diu __iomem *hw = dev_id;
	uint32_t status = in_be32(&hw->int_status);

	if (status) {
		/* This is the workaround for underrun */
		if (status & INT_UNDRUN) {
			out_be32(&hw->diu_mode, 0);
			udelay(1);
			out_be32(&hw->diu_mode, 1);
		}
#if defined(CONFIG_NOT_COHERENT_CACHE)
		else if (status & INT_VSYNC) {
			unsigned int i;

			for (i = 0; i < coherence_data_size;
				i += d_cache_line_size)
				__asm__ __volatile__ (
					"dcbz 0, %[input]"
				::[input]"r"(&coherence_data[i]));
		}
#endif
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

#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.
 */
static int fsl_diu_suspend(struct platform_device *ofdev, pm_message_t state)
{
	struct fsl_diu_data *data;

	data = dev_get_drvdata(&ofdev->dev);
	disable_lcdc(data->fsl_diu_info);

	return 0;
}

static int fsl_diu_resume(struct platform_device *ofdev)
{
	struct fsl_diu_data *data;
	unsigned int i;

	data = dev_get_drvdata(&ofdev->dev);

	fsl_diu_enable_interrupts(data);
	update_lcdc(data->fsl_diu_info);
	for (i = 0; i < NUM_AOIS; i++) {
		if (data->mfb[i].count)
			fsl_diu_enable_panel(&data->fsl_diu_info[i]);
	}

	return 0;
}

#else
#define fsl_diu_suspend NULL
#define fsl_diu_resume NULL
#endif				/* CONFIG_PM */

static ssize_t store_monitor(struct device *device,
	struct device_attribute *attr, const char *buf, size_t count)
{
	enum fsl_diu_monitor_port old_monitor_port;
	struct fsl_diu_data *data =
		container_of(attr, struct fsl_diu_data, dev_attr);

	old_monitor_port = data->monitor_port;
	data->monitor_port = fsl_diu_name_to_port(buf);

	if (old_monitor_port != data->monitor_port) {
		/* All AOIs need adjust pixel format
		 * fsl_diu_set_par only change the pixsel format here
		 * unlikely to fail. */
		unsigned int i;

		for (i=0; i < NUM_AOIS; i++)
			fsl_diu_set_par(&data->fsl_diu_info[i]);
	}
	return count;
}

static ssize_t show_monitor(struct device *device,
	struct device_attribute *attr, char *buf)
{
	struct fsl_diu_data *data =
		container_of(attr, struct fsl_diu_data, dev_attr);

	switch (data->monitor_port) {
	case FSL_DIU_PORT_DVI:
		return sprintf(buf, "DVI\n");
	case FSL_DIU_PORT_LVDS:
		return sprintf(buf, "Single-link LVDS\n");
	case FSL_DIU_PORT_DLVDS:
		return sprintf(buf, "Dual-link LVDS\n");
	}

	return 0;
}

static int fsl_diu_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct mfb_info *mfbi;
	struct fsl_diu_data *data;
	dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */
	const void *prop;
	unsigned int i;
	int ret;

	data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
				   &dma_addr, GFP_DMA | __GFP_ZERO);
	if (!data)
		return -ENOMEM;
	data->dma_addr = dma_addr;

	/*
	 * dma_alloc_coherent() uses a page allocator, so the address is
	 * always page-aligned.  We need the memory to be 32-byte aligned,
	 * so that's good.  However, if one day the allocator changes, we
	 * need to catch that.  It's not worth the effort to handle unaligned
	 * alloctions now because it's highly unlikely to ever be a problem.
	 */
	if ((unsigned long)data & 31) {
		dev_err(&pdev->dev, "misaligned allocation");
		ret = -ENOMEM;
		goto error;
	}

	spin_lock_init(&data->reg_lock);

	for (i = 0; i < NUM_AOIS; i++) {
		struct fb_info *info = &data->fsl_diu_info[i];

		info->device = &pdev->dev;
		info->par = &data->mfb[i];

		/*
		 * We store the physical address of the AD in the reserved
		 * 'paddr' field of the AD itself.
		 */
		data->ad[i].paddr = DMA_ADDR(data, ad[i]);

		info->fix.smem_start = 0;

		/* Initialize the AOI data structure */
		mfbi = info->par;
		memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
		mfbi->parent = data;
		mfbi->ad = &data->ad[i];
	}

	/* Get the EDID data from the device tree, if present */
	prop = of_get_property(np, "edid", &ret);
	if (prop && ret == EDID_LENGTH) {
		memcpy(data->edid_data, prop, EDID_LENGTH);
		data->has_edid = true;
	}

	data->diu_reg = of_iomap(np, 0);
	if (!data->diu_reg) {
		dev_err(&pdev->dev, "cannot map DIU registers\n");
		ret = -EFAULT;
		goto error;
	}

	/* Get the IRQ of the DIU */
	data->irq = irq_of_parse_and_map(np, 0);

	if (!data->irq) {
		dev_err(&pdev->dev, "could not get DIU IRQ\n");
		ret = -EINVAL;
		goto error;
	}
	data->monitor_port = monitor_port;

	/* Initialize the dummy Area Descriptor */
	data->dummy_ad.addr = cpu_to_le32(DMA_ADDR(data, dummy_aoi));
	data->dummy_ad.pix_fmt = 0x88882317;
	data->dummy_ad.src_size_g_alpha = cpu_to_le32((4 << 12) | 4);
	data->dummy_ad.aoi_size = cpu_to_le32((4 << 16) |  2);
	data->dummy_ad.offset_xyi = 0;
	data->dummy_ad.offset_xyd = 0;
	data->dummy_ad.next_ad = 0;
	data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad);

	/*
	 * Let DIU continue to display splash screen if it was pre-initialized
	 * by the bootloader; otherwise, clear the display.
	 */
	if (in_be32(&data->diu_reg->diu_mode) == MFB_MODE0)
		out_be32(&data->diu_reg->desc[0], 0);

	out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr);
	out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr);

	/*
	 * Older versions of U-Boot leave interrupts enabled, so disable
	 * all of them and clear the status register.
	 */
	out_be32(&data->diu_reg->int_mask, 0xffffffff);
	in_be32(&data->diu_reg->int_status);

	ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb",
			  data->diu_reg);
	if (ret) {
		dev_err(&pdev->dev, "could not claim irq\n");
		goto error;
	}

	for (i = 0; i < NUM_AOIS; i++) {
		ret = install_fb(&data->fsl_diu_info[i]);
		if (ret) {
			dev_err(&pdev->dev, "could not register fb %d\n", i);
			free_irq(data->irq, data->diu_reg);
			goto error;
		}
	}

	sysfs_attr_init(&data->dev_attr.attr);
	data->dev_attr.attr.name = "monitor";
	data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
	data->dev_attr.show = show_monitor;
	data->dev_attr.store = store_monitor;
	ret = device_create_file(&pdev->dev, &data->dev_attr);
	if (ret) {
		dev_err(&pdev->dev, "could not create sysfs file %s\n",
			data->dev_attr.attr.name);
	}

	dev_set_drvdata(&pdev->dev, data);
	return 0;

error:
	for (i = 0; i < NUM_AOIS; i++)
		uninstall_fb(&data->fsl_diu_info[i]);

	iounmap(data->diu_reg);

	return ret;
}

static int fsl_diu_remove(struct platform_device *pdev)
{
	struct fsl_diu_data *data;
	int i;

	data = dev_get_drvdata(&pdev->dev);
	disable_lcdc(&data->fsl_diu_info[0]);

	free_irq(data->irq, data->diu_reg);

	for (i = 0; i < NUM_AOIS; i++)
		uninstall_fb(&data->fsl_diu_info[i]);

	iounmap(data->diu_reg);

	return 0;
}

#ifndef MODULE
static int __init fsl_diu_setup(char *options)
{
	char *opt;
	unsigned long val;

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

	while ((opt = strsep(&options, ",")) != NULL) {
		if (!*opt)
			continue;
		if (!strncmp(opt, "monitor=", 8)) {
			monitor_port = fsl_diu_name_to_port(opt + 8);
		} else if (!strncmp(opt, "bpp=", 4)) {
			if (!kstrtoul(opt + 4, 10, &val))
				default_bpp = val;
		} else
			fb_mode = opt;
	}

	return 0;
}
#endif

static const struct of_device_id fsl_diu_match[] = {
#ifdef CONFIG_PPC_MPC512x
	{
		.compatible = "fsl,mpc5121-diu",
	},
#endif
	{
		.compatible = "fsl,diu",
	},
	{}
};
MODULE_DEVICE_TABLE(of, fsl_diu_match);

static struct platform_driver fsl_diu_driver = {
	.driver = {
		.name = "fsl-diu-fb",
		.of_match_table = fsl_diu_match,
	},
	.probe  	= fsl_diu_probe,
	.remove 	= fsl_diu_remove,
	.suspend	= fsl_diu_suspend,
	.resume		= fsl_diu_resume,
};

static int __init fsl_diu_init(void)
{
#ifdef CONFIG_NOT_COHERENT_CACHE
	struct device_node *np;
	const u32 *prop;
#endif
	int ret;
#ifndef MODULE
	char *option;

	/*
	 * For kernel boot options (in 'video=xxxfb:<options>' format)
	 */
	if (fb_get_options("fslfb", &option))
		return -ENODEV;
	fsl_diu_setup(option);
#else
	monitor_port = fsl_diu_name_to_port(monitor_string);
#endif

	/*
	 * Must to verify set_pixel_clock. If not implement on platform,
	 * then that means that there is no platform support for the DIU.
	 */
	if (!diu_ops.set_pixel_clock)
		return -ENODEV;

	pr_info("Freescale Display Interface Unit (DIU) framebuffer driver\n");

#ifdef CONFIG_NOT_COHERENT_CACHE
	np = of_find_node_by_type(NULL, "cpu");
	if (!np) {
		pr_err("fsl-diu-fb: can't find 'cpu' device node\n");
		return -ENODEV;
	}

	prop = of_get_property(np, "d-cache-size", NULL);
	if (prop == NULL) {
		pr_err("fsl-diu-fb: missing 'd-cache-size' property' "
		       "in 'cpu' node\n");
		of_node_put(np);
		return -ENODEV;
	}

	/*
	 * Freescale PLRU requires 13/8 times the cache size to do a proper
	 * displacement flush
	 */
	coherence_data_size = be32_to_cpup(prop) * 13;
	coherence_data_size /= 8;

	pr_debug("fsl-diu-fb: coherence data size is %zu bytes\n",
		 coherence_data_size);

	prop = of_get_property(np, "d-cache-line-size", NULL);
	if (prop == NULL) {
		pr_err("fsl-diu-fb: missing 'd-cache-line-size' property' "
		       "in 'cpu' node\n");
		of_node_put(np);
		return -ENODEV;
	}
	d_cache_line_size = be32_to_cpup(prop);

	pr_debug("fsl-diu-fb: cache lines size is %u bytes\n",
		 d_cache_line_size);

	of_node_put(np);
	coherence_data = vmalloc(coherence_data_size);
	if (!coherence_data) {
		pr_err("fsl-diu-fb: could not allocate coherence data "
		       "(size=%zu)\n", coherence_data_size);
		return -ENOMEM;
	}

#endif

	ret = platform_driver_register(&fsl_diu_driver);
	if (ret) {
		pr_err("fsl-diu-fb: failed to register platform driver\n");
#if defined(CONFIG_NOT_COHERENT_CACHE)
		vfree(coherence_data);
#endif
	}
	return ret;
}

static void __exit fsl_diu_exit(void)
{
	platform_driver_unregister(&fsl_diu_driver);
#if defined(CONFIG_NOT_COHERENT_CACHE)
	vfree(coherence_data);
#endif
}

module_init(fsl_diu_init);
module_exit(fsl_diu_exit);

MODULE_AUTHOR("York Sun <yorksun@freescale.com>");
MODULE_DESCRIPTION("Freescale DIU framebuffer driver");
MODULE_LICENSE("GPL");

module_param_named(mode, fb_mode, charp, 0);
MODULE_PARM_DESC(mode,
	"Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
module_param_named(bpp, default_bpp, ulong, 0);
MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified in 'mode'");
module_param_named(monitor, monitor_string, charp, 0);
MODULE_PARM_DESC(monitor, "Specify the monitor port "
	"(\"dvi\", \"lvds\", or \"dlvds\") if supported by the platform");

