/*
 * Epson Blizzard LCD controller driver
 *
 * Copyright (C) 2004-2005 Nokia Corporation
 * Authors:     Juha Yrjola   <juha.yrjola@nokia.com>
 *	        Imre Deak     <imre.deak@nokia.com>
 * YUV support: Jussi Laako   <jussi.laako@nokia.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/delay.h>
#include <linux/clk.h>

#include <mach/dma.h>
#include <mach/omapfb.h>
#include <mach/blizzard.h>

#include "dispc.h"

#define MODULE_NAME				"blizzard"

#define BLIZZARD_REV_CODE			0x00
#define BLIZZARD_CONFIG				0x02
#define BLIZZARD_PLL_DIV			0x04
#define BLIZZARD_PLL_LOCK_RANGE			0x06
#define BLIZZARD_PLL_CLOCK_SYNTH_0		0x08
#define BLIZZARD_PLL_CLOCK_SYNTH_1		0x0a
#define BLIZZARD_PLL_MODE			0x0c
#define BLIZZARD_CLK_SRC			0x0e
#define BLIZZARD_MEM_BANK0_ACTIVATE		0x10
#define BLIZZARD_MEM_BANK0_STATUS		0x14
#define BLIZZARD_PANEL_CONFIGURATION		0x28
#define BLIZZARD_HDISP				0x2a
#define BLIZZARD_HNDP				0x2c
#define BLIZZARD_VDISP0				0x2e
#define BLIZZARD_VDISP1				0x30
#define BLIZZARD_VNDP				0x32
#define BLIZZARD_HSW				0x34
#define BLIZZARD_VSW				0x38
#define BLIZZARD_DISPLAY_MODE			0x68
#define BLIZZARD_INPUT_WIN_X_START_0		0x6c
#define BLIZZARD_DATA_SOURCE_SELECT		0x8e
#define BLIZZARD_DISP_MEM_DATA_PORT		0x90
#define BLIZZARD_DISP_MEM_READ_ADDR0		0x92
#define BLIZZARD_POWER_SAVE			0xE6
#define BLIZZARD_NDISP_CTRL_STATUS		0xE8

/* Data source select */
/* For S1D13745 */
#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND	0x00
#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE	0x01
#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE	0x04
#define BLIZZARD_SRC_DISABLE_OVERLAY		0x05
/* For S1D13744 */
#define BLIZZARD_SRC_WRITE_LCD			0x00
#define BLIZZARD_SRC_BLT_LCD			0x06

#define BLIZZARD_COLOR_RGB565			0x01
#define BLIZZARD_COLOR_YUV420			0x09

#define BLIZZARD_VERSION_S1D13745		0x01	/* Hailstorm */
#define BLIZZARD_VERSION_S1D13744		0x02	/* Blizzard */

#define BLIZZARD_AUTO_UPDATE_TIME		(HZ / 20)

/* Reserve 4 request slots for requests in irq context */
#define REQ_POOL_SIZE			24
#define IRQ_REQ_POOL_SIZE		4

#define REQ_FROM_IRQ_POOL 0x01

#define REQ_COMPLETE	0
#define REQ_PENDING	1

struct blizzard_reg_list {
	int	start;
	int	end;
};

/* These need to be saved / restored separately from the rest. */
static const struct blizzard_reg_list blizzard_pll_regs[] = {
	{
		.start	= 0x04,		/* Don't save PLL ctrl (0x0C) */
		.end	= 0x0a,
	},
	{
		.start	= 0x0e,		/* Clock configuration */
		.end	= 0x0e,
	},
};

static const struct blizzard_reg_list blizzard_gen_regs[] = {
	{
		.start	= 0x18,		/* SDRAM control */
		.end	= 0x20,
	},
	{
		.start	= 0x28,		/* LCD Panel configuration */
		.end	= 0x5a,		/* HSSI interface, TV configuration */
	},
};

static u8 blizzard_reg_cache[0x5a / 2];

struct update_param {
	int	plane;
	int	x, y, width, height;
	int	out_x, out_y;
	int	out_width, out_height;
	int	color_mode;
	int	bpp;
	int	flags;
};

struct blizzard_request {
	struct list_head entry;
	unsigned int	 flags;

	int		 (*handler)(struct blizzard_request *req);
	void		 (*complete)(void *data);
	void		 *complete_data;

	union {
		struct update_param	update;
		struct completion	*sync;
	} par;
};

struct plane_info {
	unsigned long offset;
	int pos_x, pos_y;
	int width, height;
	int out_width, out_height;
	int scr_width;
	int color_mode;
	int bpp;
};

struct blizzard_struct {
	enum omapfb_update_mode	update_mode;
	enum omapfb_update_mode	update_mode_before_suspend;

	struct timer_list	auto_update_timer;
	int			stop_auto_update;
	struct omapfb_update_window	auto_update_window;
	int			enabled_planes;
	int			vid_nonstd_color;
	int			vid_scaled;
	int			last_color_mode;
	int			zoom_on;
	int			zoom_area_gx1;
	int			zoom_area_gx2;
	int			zoom_area_gy1;
	int			zoom_area_gy2;
	int			screen_width;
	int			screen_height;
	unsigned		te_connected:1;
	unsigned		vsync_only:1;

	struct plane_info	plane[OMAPFB_PLANE_NUM];

	struct blizzard_request	req_pool[REQ_POOL_SIZE];
	struct list_head	pending_req_list;
	struct list_head	free_req_list;
	struct semaphore	req_sema;
	spinlock_t		req_lock;

	unsigned long		sys_ck_rate;
	struct extif_timings	reg_timings, lut_timings;

	u32			max_transmit_size;
	u32			extif_clk_period;
	int			extif_clk_div;
	unsigned long		pix_tx_time;
	unsigned long		line_upd_time;

	struct omapfb_device	*fbdev;
	struct lcd_ctrl_extif	*extif;
	const struct lcd_ctrl	*int_ctrl;

	void			(*power_up)(struct device *dev);
	void			(*power_down)(struct device *dev);

	int			version;
} blizzard;

struct lcd_ctrl blizzard_ctrl;

static u8 blizzard_read_reg(u8 reg)
{
	u8 data;

	blizzard.extif->set_bits_per_cycle(8);
	blizzard.extif->write_command(&reg, 1);
	blizzard.extif->read_data(&data, 1);

	return data;
}

static void blizzard_write_reg(u8 reg, u8 val)
{
	blizzard.extif->set_bits_per_cycle(8);
	blizzard.extif->write_command(&reg, 1);
	blizzard.extif->write_data(&val, 1);
}

static void blizzard_restart_sdram(void)
{
	unsigned long tmo;

	blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
	udelay(50);
	blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 1);
	tmo = jiffies + msecs_to_jiffies(200);
	while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
		if (time_after(jiffies, tmo)) {
			dev_err(blizzard.fbdev->dev,
					"s1d1374x: SDRAM not ready\n");
			break;
		}
		msleep(1);
	}
}

static void blizzard_stop_sdram(void)
{
	blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
}

/* Wait until the last window was completely written into the controllers
 * SDRAM and we can start transferring the next window.
 */
static void blizzard_wait_line_buffer(void)
{
	unsigned long tmo = jiffies + msecs_to_jiffies(30);

	while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 7)) {
		if (time_after(jiffies, tmo)) {
			if (printk_ratelimit())
				dev_err(blizzard.fbdev->dev,
					"s1d1374x: line buffer not ready\n");
			break;
		}
	}
}

/* Wait until the YYC color space converter is idle. */
static void blizzard_wait_yyc(void)
{
	unsigned long tmo = jiffies + msecs_to_jiffies(30);

	while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 4)) {
		if (time_after(jiffies, tmo)) {
			if (printk_ratelimit())
				dev_err(blizzard.fbdev->dev,
					"s1d1374x: YYC not ready\n");
			break;
		}
	}
}

static void disable_overlay(void)
{
	blizzard_write_reg(BLIZZARD_DATA_SOURCE_SELECT,
				BLIZZARD_SRC_DISABLE_OVERLAY);
}

static void set_window_regs(int x_start, int y_start, int x_end, int y_end,
			    int x_out_start, int y_out_start,
			    int x_out_end, int y_out_end, int color_mode,
			    int zoom_off, int flags)
{
	u8 tmp[18];
	u8 cmd;

	x_end--;
	y_end--;
	tmp[0] = x_start;
	tmp[1] = x_start >> 8;
	tmp[2] = y_start;
	tmp[3] = y_start >> 8;
	tmp[4] = x_end;
	tmp[5] = x_end >> 8;
	tmp[6] = y_end;
	tmp[7] = y_end >> 8;

	x_out_end--;
	y_out_end--;
	tmp[8]  = x_out_start;
	tmp[9]  = x_out_start >> 8;
	tmp[10] = y_out_start;
	tmp[11] = y_out_start >> 8;
	tmp[12] = x_out_end;
	tmp[13] = x_out_end >> 8;
	tmp[14] = y_out_end;
	tmp[15] = y_out_end >> 8;

	tmp[16] = color_mode;
	if (zoom_off && blizzard.version == BLIZZARD_VERSION_S1D13745)
		tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
	else if (flags & OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY)
		tmp[17] = BLIZZARD_SRC_WRITE_OVERLAY_ENABLE;
	else
		tmp[17] = blizzard.version == BLIZZARD_VERSION_S1D13744 ?
				BLIZZARD_SRC_WRITE_LCD :
				BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;

	blizzard.extif->set_bits_per_cycle(8);
	cmd = BLIZZARD_INPUT_WIN_X_START_0;
	blizzard.extif->write_command(&cmd, 1);
	blizzard.extif->write_data(tmp, 18);
}

static void enable_tearsync(int y, int width, int height, int screen_height,
			    int out_height, int force_vsync)
{
	u8 b;

	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
	b |= 1 << 3;
	blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);

	if (likely(blizzard.vsync_only || force_vsync)) {
		blizzard.extif->enable_tearsync(1, 0);
		return;
	}

	if (width * blizzard.pix_tx_time < blizzard.line_upd_time) {
		blizzard.extif->enable_tearsync(1, 0);
		return;
	}

	if ((width * blizzard.pix_tx_time / 1000) * height <
	    (y + out_height) * (blizzard.line_upd_time / 1000)) {
		blizzard.extif->enable_tearsync(1, 0);
		return;
	}

	blizzard.extif->enable_tearsync(1, y + 1);
}

static void disable_tearsync(void)
{
	u8 b;

	blizzard.extif->enable_tearsync(0, 0);
	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
	b &= ~(1 << 3);
	blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
}

static inline void set_extif_timings(const struct extif_timings *t);

static inline struct blizzard_request *alloc_req(void)
{
	unsigned long flags;
	struct blizzard_request *req;
	int req_flags = 0;

	if (!in_interrupt())
		down(&blizzard.req_sema);
	else
		req_flags = REQ_FROM_IRQ_POOL;

	spin_lock_irqsave(&blizzard.req_lock, flags);
	BUG_ON(list_empty(&blizzard.free_req_list));
	req = list_entry(blizzard.free_req_list.next,
			 struct blizzard_request, entry);
	list_del(&req->entry);
	spin_unlock_irqrestore(&blizzard.req_lock, flags);

	INIT_LIST_HEAD(&req->entry);
	req->flags = req_flags;

	return req;
}

static inline void free_req(struct blizzard_request *req)
{
	unsigned long flags;

	spin_lock_irqsave(&blizzard.req_lock, flags);

	list_del(&req->entry);
	list_add(&req->entry, &blizzard.free_req_list);
	if (!(req->flags & REQ_FROM_IRQ_POOL))
		up(&blizzard.req_sema);

	spin_unlock_irqrestore(&blizzard.req_lock, flags);
}

static void process_pending_requests(void)
{
	unsigned long flags;

	spin_lock_irqsave(&blizzard.req_lock, flags);

	while (!list_empty(&blizzard.pending_req_list)) {
		struct blizzard_request *req;
		void (*complete)(void *);
		void *complete_data;

		req = list_entry(blizzard.pending_req_list.next,
				 struct blizzard_request, entry);
		spin_unlock_irqrestore(&blizzard.req_lock, flags);

		if (req->handler(req) == REQ_PENDING)
			return;

		complete = req->complete;
		complete_data = req->complete_data;
		free_req(req);

		if (complete)
			complete(complete_data);

		spin_lock_irqsave(&blizzard.req_lock, flags);
	}

	spin_unlock_irqrestore(&blizzard.req_lock, flags);
}

static void submit_req_list(struct list_head *head)
{
	unsigned long flags;
	int process = 1;

	spin_lock_irqsave(&blizzard.req_lock, flags);
	if (likely(!list_empty(&blizzard.pending_req_list)))
		process = 0;
	list_splice_init(head, blizzard.pending_req_list.prev);
	spin_unlock_irqrestore(&blizzard.req_lock, flags);

	if (process)
		process_pending_requests();
}

static void request_complete(void *data)
{
	struct blizzard_request	*req = (struct blizzard_request *)data;
	void			(*complete)(void *);
	void			*complete_data;

	complete = req->complete;
	complete_data = req->complete_data;

	free_req(req);

	if (complete)
		complete(complete_data);

	process_pending_requests();
}


static int do_full_screen_update(struct blizzard_request *req)
{
	int i;
	int flags;

	for (i = 0; i < 3; i++) {
		struct plane_info *p = &blizzard.plane[i];
		if (!(blizzard.enabled_planes & (1 << i))) {
			blizzard.int_ctrl->enable_plane(i, 0);
			continue;
		}
		dev_dbg(blizzard.fbdev->dev, "pw %d ph %d\n",
			p->width, p->height);
		blizzard.int_ctrl->setup_plane(i,
				OMAPFB_CHANNEL_OUT_LCD, p->offset,
				p->scr_width, p->pos_x, p->pos_y,
				p->width, p->height,
				p->color_mode);
		blizzard.int_ctrl->enable_plane(i, 1);
	}

	dev_dbg(blizzard.fbdev->dev, "sw %d sh %d\n",
		blizzard.screen_width, blizzard.screen_height);
	blizzard_wait_line_buffer();
	flags = req->par.update.flags;
	if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
		enable_tearsync(0, blizzard.screen_width,
				blizzard.screen_height,
				blizzard.screen_height,
				blizzard.screen_height,
				flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
	else
		disable_tearsync();

	set_window_regs(0, 0, blizzard.screen_width, blizzard.screen_height,
			0, 0, blizzard.screen_width, blizzard.screen_height,
			BLIZZARD_COLOR_RGB565, blizzard.zoom_on, flags);
	blizzard.zoom_on = 0;

	blizzard.extif->set_bits_per_cycle(16);
	/* set_window_regs has left the register index at the right
	 * place, so no need to set it here.
	 */
	blizzard.extif->transfer_area(blizzard.screen_width,
				      blizzard.screen_height,
				      request_complete, req);
	return REQ_PENDING;
}

static int check_1d_intersect(int a1, int a2, int b1, int b2)
{
	if (a2 <= b1 || b2 <= a1)
		return 0;
	return 1;
}

/* Setup all planes with an overlapping area with the update window. */
static int do_partial_update(struct blizzard_request *req, int plane,
			     int x, int y, int w, int h,
			     int x_out, int y_out, int w_out, int h_out,
			     int wnd_color_mode, int bpp)
{
	int i;
	int gx1, gy1, gx2, gy2;
	int gx1_out, gy1_out, gx2_out, gy2_out;
	int color_mode;
	int flags;
	int zoom_off;
	int have_zoom_for_this_update = 0;

	/* Global coordinates, relative to pixel 0,0 of the LCD */
	gx1 = x + blizzard.plane[plane].pos_x;
	gy1 = y + blizzard.plane[plane].pos_y;
	gx2 = gx1 + w;
	gy2 = gy1 + h;

	flags = req->par.update.flags;
	if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) {
		gx1_out = gx1;
		gy1_out = gy1;
		gx2_out = gx1 + w * 2;
		gy2_out = gy1 + h * 2;
	} else {
		gx1_out = x_out + blizzard.plane[plane].pos_x;
		gy1_out = y_out + blizzard.plane[plane].pos_y;
		gx2_out = gx1_out + w_out;
		gy2_out = gy1_out + h_out;
	}

	for (i = 0; i < OMAPFB_PLANE_NUM; i++) {
		struct plane_info *p = &blizzard.plane[i];
		int px1, py1;
		int px2, py2;
		int pw, ph;
		int pposx, pposy;
		unsigned long offset;

		if (!(blizzard.enabled_planes & (1 << i))  ||
		    (wnd_color_mode && i != plane)) {
			blizzard.int_ctrl->enable_plane(i, 0);
			continue;
		}
		/* Plane coordinates */
		if (i == plane) {
			/* Plane in which we are doing the update.
			 * Local coordinates are the one in the update
			 * request.
			 */
			px1 = x;
			py1 = y;
			px2 = x + w;
			py2 = y + h;
			pposx = 0;
			pposy = 0;
		} else {
			/* Check if this plane has an overlapping part */
			px1 = gx1 - p->pos_x;
			py1 = gy1 - p->pos_y;
			px2 = gx2 - p->pos_x;
			py2 = gy2 - p->pos_y;
			if (px1 >= p->width || py1 >= p->height ||
			    px2 <= 0 || py2 <= 0) {
				blizzard.int_ctrl->enable_plane(i, 0);
				continue;
			}
			/* Calculate the coordinates for the overlapping
			 * part in the plane's local coordinates.
			 */
			pposx = -px1;
			pposy = -py1;
			if (px1 < 0)
				px1 = 0;
			if (py1 < 0)
				py1 = 0;
			if (px2 > p->width)
				px2 = p->width;
			if (py2 > p->height)
				py2 = p->height;
			if (pposx < 0)
				pposx = 0;
			if (pposy < 0)
				pposy = 0;
		}
		pw = px2 - px1;
		ph = py2 - py1;
		offset = p->offset + (p->scr_width * py1 + px1) * p->bpp / 8;
		if (wnd_color_mode)
			/* Window embedded in the plane with a differing
			 * color mode / bpp. Calculate the number of DMA
			 * transfer elements in terms of the plane's bpp.
			 */
			pw = (pw + 1) * bpp / p->bpp;
#ifdef VERBOSE
		dev_dbg(blizzard.fbdev->dev,
			"plane %d offset %#08lx pposx %d pposy %d "
			"px1 %d py1 %d pw %d ph %d\n",
			i, offset, pposx, pposy, px1, py1, pw, ph);
#endif
		blizzard.int_ctrl->setup_plane(i,
				OMAPFB_CHANNEL_OUT_LCD, offset,
				p->scr_width,
				pposx, pposy, pw, ph,
				p->color_mode);

		blizzard.int_ctrl->enable_plane(i, 1);
	}

	switch (wnd_color_mode) {
	case OMAPFB_COLOR_YUV420:
		color_mode = BLIZZARD_COLOR_YUV420;
		/* Currently only the 16 bits/pixel cycle format is
		 * supported on the external interface. Adjust the number
		 * of transfer elements per line for 12bpp format.
		 */
		w = (w + 1) * 3 / 4;
		break;
	default:
		color_mode = BLIZZARD_COLOR_RGB565;
		break;
	}

	blizzard_wait_line_buffer();
	if (blizzard.last_color_mode == BLIZZARD_COLOR_YUV420)
		blizzard_wait_yyc();
	blizzard.last_color_mode = color_mode;
	if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
		enable_tearsync(gy1, w, h,
				blizzard.screen_height,
				h_out,
				flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
	else
		disable_tearsync();

	if ((gx2_out - gx1_out) != (gx2 - gx1) ||
	    (gy2_out - gy1_out) != (gy2 - gy1))
		have_zoom_for_this_update = 1;

	/* 'background' type of screen update (as opposed to 'destructive')
	   can be used to disable scaling if scaling is active */
	zoom_off = blizzard.zoom_on && !have_zoom_for_this_update &&
	    (gx1_out == 0) && (gx2_out == blizzard.screen_width) &&
	    (gy1_out == 0) && (gy2_out == blizzard.screen_height) &&
	    (gx1 == 0) && (gy1 == 0);

	if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off &&
	    check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2,
			       gx1_out, gx2_out) &&
	    check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2,
			       gy1_out, gy2_out)) {
		/* Previous screen update was using scaling, current update
		 * is not using it. Additionally, current screen update is
		 * going to overlap with the scaled area. Scaling needs to be
		 * disabled in order to avoid 'magnifying glass' effect.
		 * Dummy setup of background window can be used for this.
		 */
		set_window_regs(0, 0, blizzard.screen_width,
				blizzard.screen_height,
				0, 0, blizzard.screen_width,
				blizzard.screen_height,
				BLIZZARD_COLOR_RGB565, 1, flags);
		blizzard.zoom_on = 0;
	}

	/* remember scaling settings if we have scaled update */
	if (have_zoom_for_this_update) {
		blizzard.zoom_on = 1;
		blizzard.zoom_area_gx1 = gx1_out;
		blizzard.zoom_area_gx2 = gx2_out;
		blizzard.zoom_area_gy1 = gy1_out;
		blizzard.zoom_area_gy2 = gy2_out;
	}

	set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out,
			color_mode, zoom_off, flags);
	if (zoom_off)
		blizzard.zoom_on = 0;

	blizzard.extif->set_bits_per_cycle(16);
	/* set_window_regs has left the register index at the right
	 * place, so no need to set it here.
	 */
	blizzard.extif->transfer_area(w, h, request_complete, req);

	return REQ_PENDING;
}

static int send_frame_handler(struct blizzard_request *req)
{
	struct update_param *par = &req->par.update;
	int plane = par->plane;

#ifdef VERBOSE
	dev_dbg(blizzard.fbdev->dev,
		"send_frame: x %d y %d w %d h %d "
		"x_out %d y_out %d w_out %d h_out %d "
		"color_mode %04x flags %04x planes %01x\n",
		par->x, par->y, par->width, par->height,
		par->out_x, par->out_y, par->out_width, par->out_height,
		par->color_mode, par->flags, blizzard.enabled_planes);
#endif
	if (par->flags & OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY)
		disable_overlay();

	if ((blizzard.enabled_planes & blizzard.vid_nonstd_color) ||
	     (blizzard.enabled_planes & blizzard.vid_scaled))
		return do_full_screen_update(req);

	return do_partial_update(req, plane, par->x, par->y,
				 par->width, par->height,
				 par->out_x, par->out_y,
				 par->out_width, par->out_height,
				 par->color_mode, par->bpp);
}

static void send_frame_complete(void *data)
{
}

#define ADD_PREQ(_x, _y, _w, _h, _x_out, _y_out, _w_out, _h_out) do {	\
	req = alloc_req();			\
	req->handler	= send_frame_handler;	\
	req->complete	= send_frame_complete;	\
	req->par.update.plane = plane_idx;	\
	req->par.update.x = _x;			\
	req->par.update.y = _y;			\
	req->par.update.width  = _w;		\
	req->par.update.height = _h;		\
	req->par.update.out_x = _x_out;		\
	req->par.update.out_y = _y_out;		\
	req->par.update.out_width = _w_out;	\
	req->par.update.out_height = _h_out;	\
	req->par.update.bpp = bpp;		\
	req->par.update.color_mode = color_mode;\
	req->par.update.flags	  = flags;	\
	list_add_tail(&req->entry, req_head);	\
} while(0)

static void create_req_list(int plane_idx,
			    struct omapfb_update_window *win,
			    struct list_head *req_head)
{
	struct blizzard_request *req;
	int x = win->x;
	int y = win->y;
	int width = win->width;
	int height = win->height;
	int x_out = win->out_x;
	int y_out = win->out_y;
	int width_out = win->out_width;
	int height_out = win->out_height;
	int color_mode;
	int bpp;
	int flags;
	unsigned int ystart = y;
	unsigned int yspan = height;
	unsigned int ystart_out = y_out;
	unsigned int yspan_out = height_out;

	flags = win->format & ~OMAPFB_FORMAT_MASK;
	color_mode = win->format & OMAPFB_FORMAT_MASK;
	switch (color_mode) {
	case OMAPFB_COLOR_YUV420:
		/* Embedded window with different color mode */
		bpp = 12;
		/* X, Y, height must be aligned at 2, width at 4 pixels */
		x &= ~1;
		y &= ~1;
		height = yspan = height & ~1;
		width = width & ~3;
		break;
	default:
		/* Same as the plane color mode */
		bpp = blizzard.plane[plane_idx].bpp;
		break;
	}
	if (width * height * bpp / 8 > blizzard.max_transmit_size) {
		yspan = blizzard.max_transmit_size / (width * bpp / 8);
		yspan_out = yspan * height_out / height;
		ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
			 width_out, yspan_out);
		ystart += yspan;
		ystart_out += yspan_out;
		yspan = height - yspan;
		yspan_out = height_out - yspan_out;
		flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
	}

	ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
		 width_out, yspan_out);
}

static void auto_update_complete(void *data)
{
	if (!blizzard.stop_auto_update)
		mod_timer(&blizzard.auto_update_timer,
			  jiffies + BLIZZARD_AUTO_UPDATE_TIME);
}

static void blizzard_update_window_auto(unsigned long arg)
{
	LIST_HEAD(req_list);
	struct blizzard_request *last;
	struct omapfb_plane_struct *plane;

	plane = blizzard.fbdev->fb_info[0]->par;
	create_req_list(plane->idx,
			&blizzard.auto_update_window, &req_list);
	last = list_entry(req_list.prev, struct blizzard_request, entry);

	last->complete = auto_update_complete;
	last->complete_data = NULL;

	submit_req_list(&req_list);
}

int blizzard_update_window_async(struct fb_info *fbi,
				 struct omapfb_update_window *win,
				 void (*complete_callback)(void *arg),
				 void *complete_callback_data)
{
	LIST_HEAD(req_list);
	struct blizzard_request *last;
	struct omapfb_plane_struct *plane = fbi->par;

	if (unlikely(blizzard.update_mode != OMAPFB_MANUAL_UPDATE))
		return -EINVAL;
	if (unlikely(!blizzard.te_connected &&
		     (win->format & OMAPFB_FORMAT_FLAG_TEARSYNC)))
		return -EINVAL;

	create_req_list(plane->idx, win, &req_list);
	last = list_entry(req_list.prev, struct blizzard_request, entry);

	last->complete = complete_callback;
	last->complete_data = (void *)complete_callback_data;

	submit_req_list(&req_list);

	return 0;
}
EXPORT_SYMBOL(blizzard_update_window_async);

static int update_full_screen(void)
{
	return blizzard_update_window_async(blizzard.fbdev->fb_info[0],
				     &blizzard.auto_update_window, NULL, NULL);

}

static int blizzard_setup_plane(int plane, int channel_out,
				  unsigned long offset, int screen_width,
				  int pos_x, int pos_y, int width, int height,
				  int color_mode)
{
	struct plane_info *p;

#ifdef VERBOSE
	dev_dbg(blizzard.fbdev->dev,
		    "plane %d ch_out %d offset %#08lx scr_width %d "
		    "pos_x %d pos_y %d width %d height %d color_mode %d\n",
		    plane, channel_out, offset, screen_width,
		    pos_x, pos_y, width, height, color_mode);
#endif
	if ((unsigned)plane > OMAPFB_PLANE_NUM)
		return -EINVAL;
	p = &blizzard.plane[plane];

	switch (color_mode) {
	case OMAPFB_COLOR_YUV422:
	case OMAPFB_COLOR_YUY422:
		p->bpp = 16;
		blizzard.vid_nonstd_color &= ~(1 << plane);
		break;
	case OMAPFB_COLOR_YUV420:
		p->bpp = 12;
		blizzard.vid_nonstd_color |= 1 << plane;
		break;
	case OMAPFB_COLOR_RGB565:
		p->bpp = 16;
		blizzard.vid_nonstd_color &= ~(1 << plane);
		break;
	default:
		return -EINVAL;
	}

	p->offset = offset;
	p->pos_x = pos_x;
	p->pos_y = pos_y;
	p->width = width;
	p->height = height;
	p->scr_width = screen_width;
	if (!p->out_width)
		p->out_width = width;
	if (!p->out_height)
		p->out_height = height;

	p->color_mode = color_mode;

	return 0;
}

static int blizzard_set_scale(int plane, int orig_w, int orig_h,
			      int out_w, int out_h)
{
	struct plane_info *p = &blizzard.plane[plane];
	int r;

	dev_dbg(blizzard.fbdev->dev,
		"plane %d orig_w %d orig_h %d out_w %d out_h %d\n",
		plane, orig_w, orig_h, out_w, out_h);
	if ((unsigned)plane > OMAPFB_PLANE_NUM)
		return -ENODEV;

	r = blizzard.int_ctrl->set_scale(plane, orig_w, orig_h, out_w, out_h);
	if (r < 0)
		return r;

	p->width = orig_w;
	p->height = orig_h;
	p->out_width = out_w;
	p->out_height = out_h;
	if (orig_w == out_w && orig_h == out_h)
		blizzard.vid_scaled &= ~(1 << plane);
	else
		blizzard.vid_scaled |= 1 << plane;

	return 0;
}

static int blizzard_set_rotate(int angle)
{
	u32 l;

	l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION);
	l &= ~0x03;

	switch (angle) {
	case 0:
		l = l | 0x00;
		break;
	case 90:
		l = l | 0x03;
		break;
	case 180:
		l = l | 0x02;
		break;
	case 270:
		l = l | 0x01;
		break;
	default:
		return -EINVAL;
	}

	blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l);

	return 0;
}

static int blizzard_enable_plane(int plane, int enable)
{
	if (enable)
		blizzard.enabled_planes |= 1 << plane;
	else
		blizzard.enabled_planes &= ~(1 << plane);

	return 0;
}

static int sync_handler(struct blizzard_request *req)
{
	complete(req->par.sync);
	return REQ_COMPLETE;
}

static void blizzard_sync(void)
{
	LIST_HEAD(req_list);
	struct blizzard_request *req;
	struct completion comp;

	req = alloc_req();

	req->handler = sync_handler;
	req->complete = NULL;
	init_completion(&comp);
	req->par.sync = &comp;

	list_add(&req->entry, &req_list);
	submit_req_list(&req_list);

	wait_for_completion(&comp);
}


static void blizzard_bind_client(struct omapfb_notifier_block *nb)
{
	if (blizzard.update_mode == OMAPFB_MANUAL_UPDATE) {
		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
	}
}

static int blizzard_set_update_mode(enum omapfb_update_mode mode)
{
	if (unlikely(mode != OMAPFB_MANUAL_UPDATE &&
		     mode != OMAPFB_AUTO_UPDATE &&
		     mode != OMAPFB_UPDATE_DISABLED))
		return -EINVAL;

	if (mode == blizzard.update_mode)
		return 0;

	dev_info(blizzard.fbdev->dev, "s1d1374x: setting update mode to %s\n",
			mode == OMAPFB_UPDATE_DISABLED ? "disabled" :
			(mode == OMAPFB_AUTO_UPDATE ? "auto" : "manual"));

	switch (blizzard.update_mode) {
	case OMAPFB_MANUAL_UPDATE:
		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_DISABLED);
		break;
	case OMAPFB_AUTO_UPDATE:
		blizzard.stop_auto_update = 1;
		del_timer_sync(&blizzard.auto_update_timer);
		break;
	case OMAPFB_UPDATE_DISABLED:
		break;
	}

	blizzard.update_mode = mode;
	blizzard_sync();
	blizzard.stop_auto_update = 0;

	switch (mode) {
	case OMAPFB_MANUAL_UPDATE:
		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
		break;
	case OMAPFB_AUTO_UPDATE:
		blizzard_update_window_auto(0);
		break;
	case OMAPFB_UPDATE_DISABLED:
		break;
	}

	return 0;
}

static enum omapfb_update_mode blizzard_get_update_mode(void)
{
	return blizzard.update_mode;
}

static inline void set_extif_timings(const struct extif_timings *t)
{
	blizzard.extif->set_timings(t);
}

static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
{
	int bus_tick = blizzard.extif_clk_period * div;
	return (ps + bus_tick - 1) / bus_tick * bus_tick;
}

static int calc_reg_timing(unsigned long sysclk, int div)
{
	struct extif_timings *t;
	unsigned long systim;

	/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
	 * AccessTime 2 ns + 12.2 ns (regs),
	 * WEOffTime = WEOnTime + 1 ns,
	 * REOffTime = REOnTime + 12 ns (regs),
	 * CSOffTime = REOffTime + 1 ns
	 * ReadCycle = 2ns + 2*SYSCLK  (regs),
	 * WriteCycle = 2*SYSCLK + 2 ns,
	 * CSPulseWidth = 10 ns */

	systim = 1000000000 / (sysclk / 1000);
	dev_dbg(blizzard.fbdev->dev,
		  "Blizzard systim %lu ps extif_clk_period %u div %d\n",
		  systim, blizzard.extif_clk_period, div);

	t = &blizzard.reg_timings;
	memset(t, 0, sizeof(*t));

	t->clk_div = div;

	t->cs_on_time = 0;
	t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
	t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
	t->access_time = round_to_extif_ticks(t->re_on_time + 12200, div);
	t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);
	t->re_off_time = round_to_extif_ticks(t->re_on_time + 13000, div);
	t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);
	t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
	if (t->we_cycle_time < t->we_off_time)
		t->we_cycle_time = t->we_off_time;
	t->re_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
	if (t->re_cycle_time < t->re_off_time)
		t->re_cycle_time = t->re_off_time;
	t->cs_pulse_width = 0;

	dev_dbg(blizzard.fbdev->dev, "[reg]cson %d csoff %d reon %d reoff %d\n",
		 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
	dev_dbg(blizzard.fbdev->dev, "[reg]weon %d weoff %d recyc %d wecyc %d\n",
		 t->we_on_time, t->we_off_time, t->re_cycle_time,
		 t->we_cycle_time);
	dev_dbg(blizzard.fbdev->dev, "[reg]rdaccess %d cspulse %d\n",
		 t->access_time, t->cs_pulse_width);

	return blizzard.extif->convert_timings(t);
}

static int calc_lut_timing(unsigned long sysclk, int div)
{
	struct extif_timings *t;
	unsigned long systim;

	/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
	 * AccessTime 2 ns + 4 * SYSCLK + 26 (lut),
	 * WEOffTime = WEOnTime + 1 ns,
	 * REOffTime = REOnTime + 4*SYSCLK + 26 ns (lut),
	 * CSOffTime = REOffTime + 1 ns
	 * ReadCycle = 2ns + 4*SYSCLK + 26 ns (lut),
	 * WriteCycle = 2*SYSCLK + 2 ns,
	 * CSPulseWidth = 10 ns */

	systim = 1000000000 / (sysclk / 1000);
	dev_dbg(blizzard.fbdev->dev,
		"Blizzard systim %lu ps extif_clk_period %u div %d\n",
		systim, blizzard.extif_clk_period, div);

	t = &blizzard.lut_timings;
	memset(t, 0, sizeof(*t));

	t->clk_div = div;

	t->cs_on_time = 0;
	t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
	t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
	t->access_time = round_to_extif_ticks(t->re_on_time + 4 * systim +
					      26000, div);
	t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);
	t->re_off_time = round_to_extif_ticks(t->re_on_time + 4 * systim +
					      26000, div);
	t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);
	t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
	if (t->we_cycle_time < t->we_off_time)
		t->we_cycle_time = t->we_off_time;
	t->re_cycle_time = round_to_extif_ticks(2000 + 4 * systim + 26000, div);
	if (t->re_cycle_time < t->re_off_time)
		t->re_cycle_time = t->re_off_time;
	t->cs_pulse_width = 0;

	dev_dbg(blizzard.fbdev->dev,
		 "[lut]cson %d csoff %d reon %d reoff %d\n",
		 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
	dev_dbg(blizzard.fbdev->dev,
		 "[lut]weon %d weoff %d recyc %d wecyc %d\n",
		 t->we_on_time, t->we_off_time, t->re_cycle_time,
		 t->we_cycle_time);
	dev_dbg(blizzard.fbdev->dev, "[lut]rdaccess %d cspulse %d\n",
		 t->access_time, t->cs_pulse_width);

	return blizzard.extif->convert_timings(t);
}

static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
{
	int max_clk_div;
	int div;

	blizzard.extif->get_clk_info(&blizzard.extif_clk_period, &max_clk_div);
	for (div = 1; div <= max_clk_div; div++) {
		if (calc_reg_timing(sysclk, div) == 0)
			break;
	}
	if (div > max_clk_div) {
		dev_dbg(blizzard.fbdev->dev, "reg timing failed\n");
		goto err;
	}
	*extif_mem_div = div;

	for (div = 1; div <= max_clk_div; div++) {
		if (calc_lut_timing(sysclk, div) == 0)
			break;
	}

	if (div > max_clk_div)
		goto err;

	blizzard.extif_clk_div = div;

	return 0;
err:
	dev_err(blizzard.fbdev->dev, "can't setup timings\n");
	return -1;
}

static void calc_blizzard_clk_rates(unsigned long ext_clk,
				unsigned long *sys_clk, unsigned long *pix_clk)
{
	int pix_clk_src;
	int sys_div = 0, sys_mul = 0;
	int pix_div;

	pix_clk_src = blizzard_read_reg(BLIZZARD_CLK_SRC);
	pix_div = ((pix_clk_src >> 3) & 0x1f) + 1;
	if ((pix_clk_src & (0x3 << 1)) == 0) {
		/* Source is the PLL */
		sys_div = (blizzard_read_reg(BLIZZARD_PLL_DIV) & 0x3f) + 1;
		sys_mul = blizzard_read_reg(BLIZZARD_PLL_CLOCK_SYNTH_0);
		sys_mul |= ((blizzard_read_reg(BLIZZARD_PLL_CLOCK_SYNTH_1)
				& 0x0f)	<< 11);
		*sys_clk = ext_clk * sys_mul / sys_div;
	} else	/* else source is ext clk, or oscillator */
		*sys_clk = ext_clk;

	*pix_clk = *sys_clk / pix_div;			/* HZ */
	dev_dbg(blizzard.fbdev->dev,
		"ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d\n",
		ext_clk, pix_clk_src & (0x3 << 1), pix_div, sys_div, sys_mul);
	dev_dbg(blizzard.fbdev->dev, "sys_clk %ld pix_clk %ld\n",
		*sys_clk, *pix_clk);
}

static int setup_tearsync(unsigned long pix_clk, int extif_div)
{
	int hdisp, vdisp;
	int hndp, vndp;
	int hsw, vsw;
	int hs, vs;
	int hs_pol_inv, vs_pol_inv;
	int use_hsvs, use_ndp;
	u8  b;

	hsw = blizzard_read_reg(BLIZZARD_HSW);
	vsw = blizzard_read_reg(BLIZZARD_VSW);
	hs_pol_inv = !(hsw & 0x80);
	vs_pol_inv = !(vsw & 0x80);
	hsw = hsw & 0x7f;
	vsw = vsw & 0x3f;

	hdisp = blizzard_read_reg(BLIZZARD_HDISP) * 8;
	vdisp = blizzard_read_reg(BLIZZARD_VDISP0) +
		((blizzard_read_reg(BLIZZARD_VDISP1) & 0x3) << 8);

	hndp = blizzard_read_reg(BLIZZARD_HNDP) & 0x3f;
	vndp = blizzard_read_reg(BLIZZARD_VNDP);

	/* time to transfer one pixel (16bpp) in ps */
	blizzard.pix_tx_time = blizzard.reg_timings.we_cycle_time;
	if (blizzard.extif->get_max_tx_rate != NULL) {
		/* The external interface might have a rate limitation,
		 * if so, we have to maximize our transfer rate.
		 */
		unsigned long min_tx_time;
		unsigned long max_tx_rate = blizzard.extif->get_max_tx_rate();

		dev_dbg(blizzard.fbdev->dev, "max_tx_rate %ld HZ\n",
			max_tx_rate);
		min_tx_time = 1000000000 / (max_tx_rate / 1000);  /* ps */
		if (blizzard.pix_tx_time < min_tx_time)
			blizzard.pix_tx_time = min_tx_time;
	}

	/* time to update one line in ps */
	blizzard.line_upd_time = (hdisp + hndp) * 1000000 / (pix_clk / 1000);
	blizzard.line_upd_time *= 1000;
	if (hdisp * blizzard.pix_tx_time > blizzard.line_upd_time)
		/* transfer speed too low, we might have to use both
		 * HS and VS */
		use_hsvs = 1;
	else
		/* decent transfer speed, we'll always use only VS */
		use_hsvs = 0;

	if (use_hsvs && (hs_pol_inv || vs_pol_inv)) {
		/* HS or'ed with VS doesn't work, use the active high
		 * TE signal based on HNDP / VNDP */
		use_ndp = 1;
		hs_pol_inv = 0;
		vs_pol_inv = 0;
		hs = hndp;
		vs = vndp;
	} else {
		/* Use HS or'ed with VS as a TE signal if both are needed
		 * or VNDP if only vsync is needed. */
		use_ndp = 0;
		hs = hsw;
		vs = vsw;
		if (!use_hsvs) {
			hs_pol_inv = 0;
			vs_pol_inv = 0;
		}
	}

	hs = hs * 1000000 / (pix_clk / 1000);		  /* ps */
	hs *= 1000;

	vs = vs * (hdisp + hndp) * 1000000 / (pix_clk / 1000); /* ps */
	vs *= 1000;

	if (vs <= hs)
		return -EDOM;
	/* set VS to 120% of HS to minimize VS detection time */
	vs = hs * 12 / 10;
	/* minimize HS too */
	if (hs > 10000)
		hs = 10000;

	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
	b &= ~0x3;
	b |= use_hsvs ? 1 : 0;
	b |= (use_ndp && use_hsvs) ? 0 : 2;
	blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);

	blizzard.vsync_only = !use_hsvs;

	dev_dbg(blizzard.fbdev->dev,
		"pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps\n",
		pix_clk, blizzard.pix_tx_time, blizzard.line_upd_time);
	dev_dbg(blizzard.fbdev->dev,
		"hs %d ps vs %d ps mode %d vsync_only %d\n",
		hs, vs, b & 0x3, !use_hsvs);

	return blizzard.extif->setup_tearsync(1, hs, vs,
					      hs_pol_inv, vs_pol_inv,
					      extif_div);
}

static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
{
	blizzard.int_ctrl->get_caps(plane, caps);
	caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE |
		OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE |
		OMAPFB_CAPS_WINDOW_SCALE |
		OMAPFB_CAPS_WINDOW_OVERLAY |
		OMAPFB_CAPS_WINDOW_ROTATE;
	if (blizzard.te_connected)
		caps->ctrl |= OMAPFB_CAPS_TEARSYNC;
	caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) |
			   (1 << OMAPFB_COLOR_YUV420);
}

static void _save_regs(const struct blizzard_reg_list *list, int cnt)
{
	int i;

	for (i = 0; i < cnt; i++, list++) {
		int reg;
		for (reg = list->start; reg <= list->end; reg += 2)
			blizzard_reg_cache[reg / 2] = blizzard_read_reg(reg);
	}
}

static void _restore_regs(const struct blizzard_reg_list *list, int cnt)
{
	int i;

	for (i = 0; i < cnt; i++, list++) {
		int reg;
		for (reg = list->start; reg <= list->end; reg += 2)
			blizzard_write_reg(reg, blizzard_reg_cache[reg / 2]);
	}
}

static void blizzard_save_all_regs(void)
{
	_save_regs(blizzard_pll_regs, ARRAY_SIZE(blizzard_pll_regs));
	_save_regs(blizzard_gen_regs, ARRAY_SIZE(blizzard_gen_regs));
}

static void blizzard_restore_pll_regs(void)
{
	_restore_regs(blizzard_pll_regs, ARRAY_SIZE(blizzard_pll_regs));
}

static void blizzard_restore_gen_regs(void)
{
	_restore_regs(blizzard_gen_regs, ARRAY_SIZE(blizzard_gen_regs));
}

static void blizzard_suspend(void)
{
	u32 l;
	unsigned long tmo;

	if (blizzard.last_color_mode) {
		update_full_screen();
		blizzard_sync();
	}
	blizzard.update_mode_before_suspend = blizzard.update_mode;
	/* the following will disable clocks as well */
	blizzard_set_update_mode(OMAPFB_UPDATE_DISABLED);

	blizzard_save_all_regs();

	blizzard_stop_sdram();

	l = blizzard_read_reg(BLIZZARD_POWER_SAVE);
	/* Standby, Sleep. We assume we use an external clock. */
	l |= 0x03;
	blizzard_write_reg(BLIZZARD_POWER_SAVE, l);

	tmo = jiffies + msecs_to_jiffies(100);
	while (!(blizzard_read_reg(BLIZZARD_PLL_MODE) & (1 << 1))) {
		if (time_after(jiffies, tmo)) {
			dev_err(blizzard.fbdev->dev,
				"s1d1374x: sleep timeout, stopping PLL manually\n");
			l = blizzard_read_reg(BLIZZARD_PLL_MODE);
			l &= ~0x03;
			/* Disable PLL, counter function */
			l |= 0x2;
			blizzard_write_reg(BLIZZARD_PLL_MODE, l);
			break;
		}
		msleep(1);
	}

	if (blizzard.power_down != NULL)
		blizzard.power_down(blizzard.fbdev->dev);
}

static void blizzard_resume(void)
{
	u32 l;

	if (blizzard.power_up != NULL)
		blizzard.power_up(blizzard.fbdev->dev);

	l = blizzard_read_reg(BLIZZARD_POWER_SAVE);
	/* Standby, Sleep */
	l &= ~0x03;
	blizzard_write_reg(BLIZZARD_POWER_SAVE, l);

	blizzard_restore_pll_regs();
	l = blizzard_read_reg(BLIZZARD_PLL_MODE);
	l &= ~0x03;
	/* Enable PLL, counter function */
	l |= 0x1;
	blizzard_write_reg(BLIZZARD_PLL_MODE, l);

	while (!(blizzard_read_reg(BLIZZARD_PLL_DIV) & (1 << 7)))
		msleep(1);

	blizzard_restart_sdram();

	blizzard_restore_gen_regs();

	/* Enable display */
	blizzard_write_reg(BLIZZARD_DISPLAY_MODE, 0x01);

	/* the following will enable clocks as necessary */
	blizzard_set_update_mode(blizzard.update_mode_before_suspend);

	/* Force a background update */
	blizzard.zoom_on = 1;
	update_full_screen();
	blizzard_sync();
}

static int blizzard_init(struct omapfb_device *fbdev, int ext_mode,
			 struct omapfb_mem_desc *req_vram)
{
	int r = 0, i;
	u8 rev, conf;
	unsigned long ext_clk;
	int extif_div;
	unsigned long sys_clk, pix_clk;
	struct omapfb_platform_data *omapfb_conf;
	struct blizzard_platform_data *ctrl_conf;

	blizzard.fbdev = fbdev;

	BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl);

	blizzard.fbdev = fbdev;
	blizzard.extif = fbdev->ext_if;
	blizzard.int_ctrl = fbdev->int_ctrl;

	omapfb_conf = fbdev->dev->platform_data;
	ctrl_conf = omapfb_conf->ctrl_platform_data;
	if (ctrl_conf == NULL || ctrl_conf->get_clock_rate == NULL) {
		dev_err(fbdev->dev, "s1d1374x: missing platform data\n");
		r = -ENOENT;
		goto err1;
	}

	blizzard.power_down = ctrl_conf->power_down;
	blizzard.power_up = ctrl_conf->power_up;

	spin_lock_init(&blizzard.req_lock);

	if ((r = blizzard.int_ctrl->init(fbdev, 1, req_vram)) < 0)
		goto err1;

	if ((r = blizzard.extif->init(fbdev)) < 0)
		goto err2;

	blizzard_ctrl.set_color_key = blizzard.int_ctrl->set_color_key;
	blizzard_ctrl.get_color_key = blizzard.int_ctrl->get_color_key;
	blizzard_ctrl.setup_mem = blizzard.int_ctrl->setup_mem;
	blizzard_ctrl.mmap = blizzard.int_ctrl->mmap;

	ext_clk = ctrl_conf->get_clock_rate(fbdev->dev);
	if ((r = calc_extif_timings(ext_clk, &extif_div)) < 0)
		goto err3;

	set_extif_timings(&blizzard.reg_timings);

	if (blizzard.power_up != NULL)
		blizzard.power_up(fbdev->dev);

	calc_blizzard_clk_rates(ext_clk, &sys_clk, &pix_clk);

	if ((r = calc_extif_timings(sys_clk, &extif_div)) < 0)
		goto err3;
	set_extif_timings(&blizzard.reg_timings);

	if (!(blizzard_read_reg(BLIZZARD_PLL_DIV) & 0x80)) {
		dev_err(fbdev->dev,
			"controller not initialized by the bootloader\n");
		r = -ENODEV;
		goto err3;
	}

	if (ctrl_conf->te_connected) {
		if ((r = setup_tearsync(pix_clk, extif_div)) < 0)
			goto err3;
		blizzard.te_connected = 1;
	}

	rev = blizzard_read_reg(BLIZZARD_REV_CODE);
	conf = blizzard_read_reg(BLIZZARD_CONFIG);

	switch (rev & 0xfc) {
	case 0x9c:
		blizzard.version = BLIZZARD_VERSION_S1D13744;
		pr_info("omapfb: s1d13744 LCD controller rev %d "
			"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
		break;
	case 0xa4:
		blizzard.version = BLIZZARD_VERSION_S1D13745;
		pr_info("omapfb: s1d13745 LCD controller rev %d "
			"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
		break;
	default:
		dev_err(fbdev->dev, "invalid s1d1374x revision %02x\n",
			rev);
		r = -ENODEV;
		goto err3;
	}

	blizzard.max_transmit_size = blizzard.extif->max_transmit_size;

	blizzard.update_mode = OMAPFB_UPDATE_DISABLED;

	blizzard.auto_update_window.x = 0;
	blizzard.auto_update_window.y = 0;
	blizzard.auto_update_window.width = fbdev->panel->x_res;
	blizzard.auto_update_window.height = fbdev->panel->y_res;
	blizzard.auto_update_window.out_x = 0;
	blizzard.auto_update_window.out_x = 0;
	blizzard.auto_update_window.out_width = fbdev->panel->x_res;
	blizzard.auto_update_window.out_height = fbdev->panel->y_res;
	blizzard.auto_update_window.format = 0;

	blizzard.screen_width = fbdev->panel->x_res;
	blizzard.screen_height = fbdev->panel->y_res;

	init_timer(&blizzard.auto_update_timer);
	blizzard.auto_update_timer.function = blizzard_update_window_auto;
	blizzard.auto_update_timer.data = 0;

	INIT_LIST_HEAD(&blizzard.free_req_list);
	INIT_LIST_HEAD(&blizzard.pending_req_list);
	for (i = 0; i < ARRAY_SIZE(blizzard.req_pool); i++)
		list_add(&blizzard.req_pool[i].entry, &blizzard.free_req_list);
	BUG_ON(i <= IRQ_REQ_POOL_SIZE);
	sema_init(&blizzard.req_sema, i - IRQ_REQ_POOL_SIZE);

	return 0;
err3:
	if (blizzard.power_down != NULL)
		blizzard.power_down(fbdev->dev);
	blizzard.extif->cleanup();
err2:
	blizzard.int_ctrl->cleanup();
err1:
	return r;
}

static void blizzard_cleanup(void)
{
	blizzard_set_update_mode(OMAPFB_UPDATE_DISABLED);
	blizzard.extif->cleanup();
	blizzard.int_ctrl->cleanup();
	if (blizzard.power_down != NULL)
		blizzard.power_down(blizzard.fbdev->dev);
}

struct lcd_ctrl blizzard_ctrl = {
	.name			= "blizzard",
	.init			= blizzard_init,
	.cleanup		= blizzard_cleanup,
	.bind_client		= blizzard_bind_client,
	.get_caps		= blizzard_get_caps,
	.set_update_mode	= blizzard_set_update_mode,
	.get_update_mode	= blizzard_get_update_mode,
	.setup_plane		= blizzard_setup_plane,
	.set_scale		= blizzard_set_scale,
	.enable_plane		= blizzard_enable_plane,
	.set_rotate		= blizzard_set_rotate,
	.update_window		= blizzard_update_window_async,
	.sync			= blizzard_sync,
	.suspend		= blizzard_suspend,
	.resume			= blizzard_resume,
};

