/*
 * drivers/video/pnx4008/sdum.c
 *
 * Display Update Master support
 *
 * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
 *          Vitaly Wool <vitalywool@gmail.com>
 * Based on Philips Semiconductors's code
 *
 * Copyrght (c) 2005-2006 MontaVista Software, Inc.
 * Copyright (c) 2005 Philips Semiconductors
 * This file is licensed under the terms of the GNU General Public License
 * version 2. This program is licensed "as is" without any warranty of any
 * kind, whether express or implied.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
#include <linux/gfp.h>
#include <asm/uaccess.h>
#include <mach/gpio.h>

#include "sdum.h"
#include "fbcommon.h"
#include "dum.h"

/* Framebuffers we have */

static struct pnx4008_fb_addr {
	int fb_type;
	long addr_offset;
	long fb_length;
} fb_addr[] = {
	[0] = {
		FB_TYPE_YUV, 0, 0xB0000
	},
	[1] = {
		FB_TYPE_RGB, 0xB0000, 0x50000
	},
};

static struct dum_data {
	u32 lcd_phys_start;
	u32 lcd_virt_start;
	u32 slave_phys_base;
	u32 *slave_virt_base;
	int fb_owning_channel[MAX_DUM_CHANNELS];
	struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS];
} dum_data;

/* Different local helper functions */

static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup)
{
	return (ch_setup->xmax - ch_setup->xmin + 1);
}

static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup)
{
	return (ch_setup->ymax - ch_setup->ymin + 1);
}

static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup)
{
	return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup));
}

static u32 nof_bytes(struct dum_ch_setup *ch_setup)
{
	u32 r = nof_pixels_dxy(ch_setup);
	switch (ch_setup->format) {
	case RGB888:
	case RGB666:
		r *= 4;
		break;

	default:
		r *= 2;
		break;
	}
	return r;
}

static u32 build_command(int disp_no, u32 reg, u32 val)
{
	return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) |
		(reg << 0));
}

static u32 build_double_index(int disp_no, u32 val)
{
	return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0));
}

static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw)
{
	dw->ymin = ch_setup->ymin;
	dw->ymax = ch_setup->ymax;
	dw->xmin_l = ch_setup->xmin & 0xFF;
	dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8;
	dw->xmax_l = ch_setup->xmax & 0xFF;
	dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8;
}

static int put_channel(struct dumchannel chan)
{
	int i = chan.channelnr;

	if (i < 0 || i > MAX_DUM_CHANNELS)
		return -EINVAL;
	else {
		DUM_CH_MIN(i) = chan.dum_ch_min;
		DUM_CH_MAX(i) = chan.dum_ch_max;
		DUM_CH_CONF(i) = chan.dum_ch_conf;
		DUM_CH_CTRL(i) = chan.dum_ch_ctrl;
	}

	return 0;
}

static void clear_channel(int channr)
{
	struct dumchannel chan;

	chan.channelnr = channr;
	chan.dum_ch_min = 0;
	chan.dum_ch_max = 0;
	chan.dum_ch_conf = 0;
	chan.dum_ch_ctrl = 0;

	put_channel(chan);
}

static int put_cmd_string(struct cmdstring cmds)
{
	u16 *cmd_str_virtaddr;
	u32 *cmd_ptr0_virtaddr;
	u32 cmd_str_physaddr;

	int i = cmds.channelnr;

	if (i < 0 || i > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if ((cmd_ptr0_virtaddr =
		  (int *)ioremap_nocache(DUM_COM_BASE,
					 sizeof(int) * MAX_DUM_CHANNELS)) ==
		 NULL)
		return -EIOREMAPFAILED;
	else {
		cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]);
		if ((cmd_str_virtaddr =
		     (u16 *) ioremap_nocache(cmd_str_physaddr,
					     sizeof(cmds))) == NULL) {
			iounmap(cmd_ptr0_virtaddr);
			return -EIOREMAPFAILED;
		} else {
			int t;
			for (t = 0; t < 8; t++)
				iowrite16(*((u16 *)&cmds.prestringlen + t),
					  cmd_str_virtaddr + t);

			for (t = 0; t < cmds.prestringlen / 2; t++)
				 iowrite16(*((u16 *)&cmds.precmd + t),
					   cmd_str_virtaddr + t + 8);

			for (t = 0; t < cmds.poststringlen / 2; t++)
				iowrite16(*((u16 *)&cmds.postcmd + t),
					  cmd_str_virtaddr + t + 8 +
					  	cmds.prestringlen / 2);

			iounmap(cmd_ptr0_virtaddr);
			iounmap(cmd_str_virtaddr);
		}
	}

	return 0;
}

static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup)
{
	struct cmdstring cmds_c;
	struct cmdstring *cmds = &cmds_c;
	struct disp_window dw;
	int standard;
	u32 orientation = 0;
	struct dumchannel chan = { 0 };
	int ret;

	if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) {
		standard = 0;

		orientation = BIT(1);	/* always set 9-bit-bus */
		if (ch_setup->xmirror)
			orientation |= BIT(4);
		if (ch_setup->ymirror)
			orientation |= BIT(3);
		if (ch_setup->rotate)
			orientation |= BIT(0);
	} else
		standard = 1;

	cmds->channelnr = ch_no;

	/* build command string header */
	if (standard) {
		cmds->prestringlen = 32;
		cmds->poststringlen = 0;
	} else {
		cmds->prestringlen = 48;
		cmds->poststringlen = 16;
	}

	cmds->format =
	    (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format));
	cmds->reserved = 0x0;
	cmds->startaddr_low = (ch_setup->minadr & 0xFFFF);
	cmds->startaddr_high = (ch_setup->minadr >> 16);

	if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0)
	    && (ch_setup->xmin == 0)
	    && (ch_setup->ymin == 0) && (ch_setup->xmax == 0)
	    && (ch_setup->ymax == 0)) {
		cmds->pixdatlen_low = 0;
		cmds->pixdatlen_high = 0;
	} else {
		u32 nbytes = nof_bytes(ch_setup);
		cmds->pixdatlen_low = (nbytes & 0xFFFF);
		cmds->pixdatlen_high = (nbytes >> 16);
	}

	if (ch_setup->slave_trans)
		cmds->pixdatlen_high |= BIT(15);

	/* build pre-string */
	build_disp_window(ch_setup, &dw);

	if (standard) {
		cmds->precmd[0] =
		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99);
		cmds->precmd[1] =
		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
				  dw.xmin_l);
		cmds->precmd[2] =
		    build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
				  dw.xmin_h);
		cmds->precmd[3] =
		    build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
		cmds->precmd[4] =
		    build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
				  dw.xmax_l);
		cmds->precmd[5] =
		    build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
				  dw.xmax_h);
		cmds->precmd[6] =
		    build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
		cmds->precmd[7] =
		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
	} else {
		if (dw.xmin_l == ch_no)
			cmds->precmd[0] =
			    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
					  0x99);
		else
			cmds->precmd[0] =
			    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
					  ch_no);

		cmds->precmd[1] =
		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
				  dw.xmin_l);
		cmds->precmd[2] =
		    build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
				  dw.xmin_h);
		cmds->precmd[3] =
		    build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
		cmds->precmd[4] =
		    build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
				  dw.xmax_l);
		cmds->precmd[5] =
		    build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
				  dw.xmax_h);
		cmds->precmd[6] =
		    build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
		cmds->precmd[7] =
		    build_command(ch_setup->disp_no, DISP_1_REG, orientation);
		cmds->precmd[8] =
		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
		cmds->precmd[9] =
		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
		cmds->precmd[0xA] =
		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
		cmds->precmd[0xB] =
		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
		cmds->postcmd[0] =
		    build_command(ch_setup->disp_no, DISP_1_REG, BIT(1));
		cmds->postcmd[1] =
		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1);
		cmds->postcmd[2] =
		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2);
		cmds->postcmd[3] =
		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3);
	}

	if ((ret = put_cmd_string(cmds_c)) != 0) {
		return ret;
	}

	chan.channelnr = cmds->channelnr;
	chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr;
	chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr;
	chan.dum_ch_conf = 0x002;
	chan.dum_ch_ctrl = 0x04;

	put_channel(chan);

	return 0;
}

static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer,
			u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h)
{

	struct dum_ch_setup k;
	int ret;

	/* keep width & height within display area */
	if ((xpos + w) > DISP_MAX_X_SIZE)
		w = DISP_MAX_X_SIZE - xpos;

	if ((ypos + h) > DISP_MAX_Y_SIZE)
		h = DISP_MAX_Y_SIZE - ypos;

	/* assume 1 display only */
	k.disp_no = 0;
	k.xmin = xpos;
	k.ymin = ypos;
	k.xmax = xpos + (w - 1);
	k.ymax = ypos + (h - 1);

	/* adjust min and max values if necessary */
	if (k.xmin > DISP_MAX_X_SIZE - 1)
		k.xmin = DISP_MAX_X_SIZE - 1;
	if (k.ymin > DISP_MAX_Y_SIZE - 1)
		k.ymin = DISP_MAX_Y_SIZE - 1;

	if (k.xmax > DISP_MAX_X_SIZE - 1)
		k.xmax = DISP_MAX_X_SIZE - 1;
	if (k.ymax > DISP_MAX_Y_SIZE - 1)
		k.ymax = DISP_MAX_Y_SIZE - 1;

	k.xmirror = 0;
	k.ymirror = 0;
	k.rotate = 0;
	k.minadr = (u32) frame_buffer;
	k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2));
	k.pad = PAD_1024;
	k.dirtybuffer = (u32) dirty_buffer;
	k.format = RGB888;
	k.hwdirty = 0;
	k.slave_trans = 0;

	ret = dum_ch_setup(ch_no, &k);

	return ret;
}

static void lcd_reset(void)
{
	u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE);

	udelay(1);
	iowrite32(BIT(19), &dum_pio_base[2]);
	udelay(1);
	iowrite32(BIT(19), &dum_pio_base[1]);
	udelay(1);
}

static int dum_init(struct platform_device *pdev)
{
	struct clk *clk;

	/* enable DUM clock */
	clk = clk_get(&pdev->dev, "dum_ck");
	if (IS_ERR(clk)) {
		printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n");
		return PTR_ERR(clk);
	}

	clk_set_rate(clk, 1);
	clk_put(clk);

	DUM_CTRL = V_DUM_RESET;

	/* set priority to "round-robin". All other params to "false" */
	DUM_CONF = BIT(9);

	/* Display 1 */
	DUM_WTCFG1 = PNX4008_DUM_WT_CFG;
	DUM_RTCFG1 = PNX4008_DUM_RT_CFG;
	DUM_TCFG = PNX4008_DUM_T_CFG;

	return 0;
}

static void dum_chan_init(void)
{
	int i = 0, ch = 0;
	u32 *cmdptrs;
	u32 *cmdstrings;

	DUM_COM_BASE =
		CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS;

	if ((cmdptrs =
	     (u32 *) ioremap_nocache(DUM_COM_BASE,
				     sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL)
		return;

	for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++)
		iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch,
			  cmdptrs + ch);

	for (ch = 0; ch < MAX_DUM_CHANNELS; ch++)
		clear_channel(ch);

	/* Clear the cmdstrings */
	cmdstrings =
	    (u32 *)ioremap_nocache(*cmdptrs,
				   BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS);

	if (!cmdstrings)
		goto out;

	for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32);
	     i++)
		iowrite32(0, cmdstrings + i);

	iounmap((u32 *)cmdstrings);

out:
	iounmap((u32 *)cmdptrs);
}

static void lcd_init(void)
{
	lcd_reset();

	DUM_OUTP_FORMAT1 = 0; /* RGB666 */

	udelay(1);
	iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base);
	udelay(1);
	iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base);
	udelay(1);
}

/* Interface exported to framebuffer drivers */

int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
			     dma_addr_t *phys_addr, int *fb_length)
{
	int i;
	int ret = -1;
	for (i = 0; i < ARRAY_SIZE(fb_addr); i++)
		if (fb_addr[i].fb_type == fb_type) {
			*virt_addr = (void *)(dum_data.lcd_virt_start +
					fb_addr[i].addr_offset);
			*phys_addr =
			    dum_data.lcd_phys_start + fb_addr[i].addr_offset;
			*fb_length = fb_addr[i].fb_length;
			ret = 0;
			break;
		}

	return ret;
}

EXPORT_SYMBOL(pnx4008_get_fb_addresses);

int pnx4008_alloc_dum_channel(int dev_id)
{
	int i = 0;

	while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1))
		i++;

	if (i == MAX_DUM_CHANNELS)
		return -ENORESOURCESLEFT;
	else {
		dum_data.fb_owning_channel[i] = dev_id;
		return i;
	}
}

EXPORT_SYMBOL(pnx4008_alloc_dum_channel);

int pnx4008_free_dum_channel(int channr, int dev_id)
{
	if (channr < 0 || channr > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if (dum_data.fb_owning_channel[channr] != dev_id)
		return -EFBNOTOWNER;
	else {
		clear_channel(channr);
		dum_data.fb_owning_channel[channr] = -1;
	}

	return 0;
}

EXPORT_SYMBOL(pnx4008_free_dum_channel);

int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id)
{
	int i = chan_uf.channelnr;
	int ret;

	if (i < 0 || i > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if (dum_data.fb_owning_channel[i] != dev_id)
		return -EFBNOTOWNER;
	else if ((ret =
		  display_open(chan_uf.channelnr, 0, chan_uf.dirty,
			       chan_uf.source, chan_uf.y_offset,
			       chan_uf.x_offset, chan_uf.height,
			       chan_uf.width)) != 0)
		return ret;
	else {
		dum_data.chan_uf_store[i].dirty = chan_uf.dirty;
		dum_data.chan_uf_store[i].source = chan_uf.source;
		dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset;
		dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset;
		dum_data.chan_uf_store[i].width = chan_uf.width;
		dum_data.chan_uf_store[i].height = chan_uf.height;
	}

	return 0;
}

EXPORT_SYMBOL(pnx4008_put_dum_channel_uf);

int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id)
{
	if (channr < 0 || channr > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if (dum_data.fb_owning_channel[channr] != dev_id)
		return -EFBNOTOWNER;
	else {
		if (val == CONF_SYNC_ON) {
			DUM_CH_CONF(channr) |= CONF_SYNCENABLE;
			DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK |
				DUM_CHANNEL_CFG_SYNC_MASK_SET;
		} else if (val == CONF_SYNC_OFF)
			DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE;
		else
			return -EINVAL;
	}

	return 0;
}

EXPORT_SYMBOL(pnx4008_set_dum_channel_sync);

int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id)
{
	if (channr < 0 || channr > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if (dum_data.fb_owning_channel[channr] != dev_id)
		return -EFBNOTOWNER;
	else {
		if (val == CONF_DIRTYDETECTION_ON)
			DUM_CH_CONF(channr) |= CONF_DIRTYENABLE;
		else if (val == CONF_DIRTYDETECTION_OFF)
			DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE;
		else
			return -EINVAL;
	}

	return 0;
}

EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect);

#if 0 /* Functions not used currently, but likely to be used in future */

static int get_channel(struct dumchannel *p_chan)
{
	int i = p_chan->channelnr;

	if (i < 0 || i > MAX_DUM_CHANNELS)
		return -EINVAL;
	else {
		p_chan->dum_ch_min = DUM_CH_MIN(i);
		p_chan->dum_ch_max = DUM_CH_MAX(i);
		p_chan->dum_ch_conf = DUM_CH_CONF(i);
		p_chan->dum_ch_stat = DUM_CH_STAT(i);
		p_chan->dum_ch_ctrl = 0;	/* WriteOnly control register */
	}

	return 0;
}

int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id)
{
	int i = p_chan_uf->channelnr;

	if (i < 0 || i > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if (dum_data.fb_owning_channel[i] != dev_id)
		return -EFBNOTOWNER;
	else {
		p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty;
		p_chan_uf->source = dum_data.chan_uf_store[i].source;
		p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset;
		p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset;
		p_chan_uf->width = dum_data.chan_uf_store[i].width;
		p_chan_uf->height = dum_data.chan_uf_store[i].height;
	}

	return 0;
}

EXPORT_SYMBOL(pnx4008_get_dum_channel_uf);

int pnx4008_get_dum_channel_config(int channr, int dev_id)
{
	int ret;
	struct dumchannel chan;

	if (channr < 0 || channr > MAX_DUM_CHANNELS)
		return -EINVAL;
	else if (dum_data.fb_owning_channel[channr] != dev_id)
		return -EFBNOTOWNER;
	else {
		chan.channelnr = channr;
		if ((ret = get_channel(&chan)) != 0)
			return ret;
	}

	return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK);
}

EXPORT_SYMBOL(pnx4008_get_dum_channel_config);

int pnx4008_force_update_dum_channel(int channr, int dev_id)
{
	if (channr < 0 || channr > MAX_DUM_CHANNELS)
		return -EINVAL;

	else if (dum_data.fb_owning_channel[channr] != dev_id)
		return -EFBNOTOWNER;
	else
		DUM_CH_CTRL(channr) = CTRL_SETDIRTY;

	return 0;
}

EXPORT_SYMBOL(pnx4008_force_update_dum_channel);

#endif

int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma,
		      struct device *dev)
{
	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;

	if (off < info->fix.smem_len) {
		vma->vm_pgoff += 1;
		return dma_mmap_writecombine(dev, vma,
				(void *)dum_data.lcd_virt_start,
				dum_data.lcd_phys_start,
				FB_DMA_SIZE);
	}
	return -EINVAL;
}

EXPORT_SYMBOL(pnx4008_sdum_mmap);

int pnx4008_set_dum_exit_notification(int dev_id)
{
	int i;

	for (i = 0; i < MAX_DUM_CHANNELS; i++)
		if (dum_data.fb_owning_channel[i] == dev_id)
			return -ERESOURCESNOTFREED;

	return 0;
}

EXPORT_SYMBOL(pnx4008_set_dum_exit_notification);

/* Platform device driver for DUM */

static int sdum_suspend(struct platform_device *pdev, pm_message_t state)
{
	int retval = 0;
	struct clk *clk;

	clk = clk_get(0, "dum_ck");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, 0);
		clk_put(clk);
	} else
		retval = PTR_ERR(clk);

	/* disable BAC */
	DUM_CTRL = V_BAC_DISABLE_IDLE;

	/* LCD standby & turn off display */
	lcd_reset();

	return retval;
}

static int sdum_resume(struct platform_device *pdev)
{
	int retval = 0;
	struct clk *clk;

	clk = clk_get(0, "dum_ck");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, 1);
		clk_put(clk);
	} else
		retval = PTR_ERR(clk);

	/* wait for BAC disable */
	DUM_CTRL = V_BAC_DISABLE_TRIG;

	while (DUM_CTRL & BAC_ENABLED)
		udelay(10);

	/* re-init LCD */
	lcd_init();

	/* enable BAC and reset MUX */
	DUM_CTRL = V_BAC_ENABLE;
	udelay(1);
	DUM_CTRL = V_MUX_RESET;
	return 0;
}

static int __devinit sdum_probe(struct platform_device *pdev)
{
	int ret = 0, i = 0;

	/* map frame buffer */
	dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev,
						       FB_DMA_SIZE,
						       &dum_data.lcd_phys_start,
						       GFP_KERNEL);

	if (!dum_data.lcd_virt_start) {
		ret = -ENOMEM;
		goto out_3;
	}

	/* map slave registers */
	dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE;
	dum_data.slave_virt_base =
	    (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32));

	if (dum_data.slave_virt_base == NULL) {
		ret = -ENOMEM;
		goto out_2;
	}

	/* initialize DUM and LCD display */
	ret = dum_init(pdev);
	if (ret)
		goto out_1;

	dum_chan_init();
	lcd_init();

	DUM_CTRL = V_BAC_ENABLE;
	udelay(1);
	DUM_CTRL = V_MUX_RESET;

	/* set decode address and sync clock divider */
	DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK;
	DUM_CLK_DIV = PNX4008_DUM_CLK_DIV;

	for (i = 0; i < MAX_DUM_CHANNELS; i++)
		dum_data.fb_owning_channel[i] = -1;

	/*setup wakeup interrupt */
	start_int_set_rising_edge(SE_DISP_SYNC_INT);
	start_int_ack(SE_DISP_SYNC_INT);
	start_int_umask(SE_DISP_SYNC_INT);

	return 0;

out_1:
	iounmap((void *)dum_data.slave_virt_base);
out_2:
	dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
			(void *)dum_data.lcd_virt_start,
			dum_data.lcd_phys_start);
out_3:
	return ret;
}

static int sdum_remove(struct platform_device *pdev)
{
	struct clk *clk;

	start_int_mask(SE_DISP_SYNC_INT);

	clk = clk_get(0, "dum_ck");
	if (!IS_ERR(clk)) {
		clk_set_rate(clk, 0);
		clk_put(clk);
	}

	iounmap((void *)dum_data.slave_virt_base);

	dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
			(void *)dum_data.lcd_virt_start,
			dum_data.lcd_phys_start);

	return 0;
}

static struct platform_driver sdum_driver = {
	.driver = {
		.name = "pnx4008-sdum",
	},
	.probe = sdum_probe,
	.remove = sdum_remove,
	.suspend = sdum_suspend,
	.resume = sdum_resume,
};

int __init sdum_init(void)
{
	return platform_driver_register(&sdum_driver);
}

static void __exit sdum_exit(void)
{
	platform_driver_unregister(&sdum_driver);
};

module_init(sdum_init);
module_exit(sdum_exit);

MODULE_LICENSE("GPL");
