1f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*
2f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * BRIEF MODULE DESCRIPTION
3f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *	Au1200 LCD Driver.
4f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *
5f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Copyright 2004-2005 AMD
6f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Author: AMD
7f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *
8f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Based on:
9f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
10f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  Created 28 Dec 1997 by Geert Uytterhoeven
11f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *
12f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  This program is free software; you can redistribute	 it and/or modify it
13f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  under  the terms of	 the GNU General  Public License as published by the
14f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  Free Software Foundation;  either version 2 of the	License, or (at your
15f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  option) any later version.
16f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *
17f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
18f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
19f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
20f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
21f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
23f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
25f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *
28f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  You should have received a copy of the  GNU General Public License along
29f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  with this program; if not, write  to the Free Software Foundation, Inc.,
30f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *  675 Mass Ave, Cambridge, MA 02139, USA.
31f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
32f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
33ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss#include <linux/clk.h>
34f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/module.h>
35f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/platform_device.h>
36f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/kernel.h>
37f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/errno.h>
38f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/string.h>
39f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/mm.h>
40f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/fb.h>
41f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/init.h>
42f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/interrupt.h>
43f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/ctype.h>
44f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <linux/dma-mapping.h>
455a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
46f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
47f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include <asm/mach-au1x00/au1000.h>
48a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss#include <asm/mach-au1x00/au1200fb.h>	/* platform_data */
49f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#include "au1200fb.h"
50f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
51f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define DRIVER_NAME "au1200fb"
52f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define DRIVER_DESC "LCD controller driver for AU1200 processors"
53f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
54f49446ebdb043344058f67d25fbb7e3d9b306511Manuel Lauss#define DEBUG 0
55f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
56f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
57f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
58f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
59f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
60f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if DEBUG
61f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
62f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#else
63f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define print_dbg(f, arg...) do {} while (0)
64f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
65f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
66f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
67f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_FB_IOCTL 0x46FF
68f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
69f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_SET_SCREEN 1
70f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_GET_SCREEN 2
71f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_SET_WINDOW 3
72f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_GET_WINDOW 4
73f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_SET_PANEL  5
74f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_GET_PANEL  6
75f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
76f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define SCREEN_SIZE		    (1<< 1)
77f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define SCREEN_BACKCOLOR    (1<< 2)
78f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define SCREEN_BRIGHTNESS   (1<< 3)
79f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define SCREEN_COLORKEY     (1<< 4)
80f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define SCREEN_MASK         (1<< 5)
81f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
82f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestruct au1200_lcd_global_regs_t {
83f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int flags;
84f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int xsize;
85f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int ysize;
86f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int backcolor;
87f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int brightness;
88f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int colorkey;
89f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int mask;
90f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int panel_choice;
91f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	char panel_desc[80];
92f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
93f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
94f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
95f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_POSITION            (1<< 0)
96f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_ALPHA_COLOR         (1<< 1)
97f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_ALPHA_MODE          (1<< 2)
98f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_PRIORITY            (1<< 3)
99f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_CHANNEL             (1<< 4)
100f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_BUFFER_FORMAT       (1<< 5)
101f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_COLOR_ORDER         (1<< 6)
102f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_PIXEL_ORDER         (1<< 7)
103f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_SIZE                (1<< 8)
104f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_COLORKEY_MODE       (1<< 9)
105f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_DOUBLE_BUFFER_MODE  (1<< 10)
106f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_RAM_ARRAY_MODE      (1<< 11)
107f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_BUFFER_SCALE        (1<< 12)
108f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define WIN_ENABLE	            (1<< 13)
109f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
110f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestruct au1200_lcd_window_regs_t {
111f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int flags;
112f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int xpos;
113f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int ypos;
114f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int alpha_color;
115f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int alpha_mode;
116f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int priority;
117f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int channel;
118f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int buffer_format;
119f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int color_order;
120f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int pixel_order;
121f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int xsize;
122f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int ysize;
123f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int colorkey_mode;
124f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int double_buffer_mode;
125f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int ram_array_mode;
126f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int xscale;
127f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int yscale;
128f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int enable;
129f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
130f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
131f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
132f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestruct au1200_lcd_iodata_t {
133f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int subcmd;
134f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct au1200_lcd_global_regs_t global;
135f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct au1200_lcd_window_regs_t window;
136f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
137f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
138f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if defined(__BIG_ENDIAN)
139f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
140f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#else
141f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
142f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
143f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
144f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
145f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* Private, per-framebuffer management information (independent of the panel itself) */
146f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestruct au1200fb_device {
147c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct fb_info *fb_info;		/* FB driver info record */
148a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_platdata *pd;
149f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
150f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int					plane;
151f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned char* 		fb_mem;		/* FrameBuffer memory map */
152f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int		fb_len;
153f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	dma_addr_t    		fb_phys;
154f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
155f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
156f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/********************************************************************/
157f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
158f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* LCD controller restrictions */
159f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_MAX_XRES	1280
160f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_MAX_YRES	1024
161f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_MAX_BPP	32
162f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_MAX_CLK	96000000 /* fixme: this needs to go away ? */
163f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200_LCD_NBR_PALETTE_ENTRIES 256
164f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
165f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* Default number of visible screen buffer to allocate */
166f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define AU1200FB_NBR_VIDEO_BUFFERS 1
167f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1688be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss/* Default maximum number of fb devices to create */
1698be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss#define MAX_DEVICE_COUNT	4
1708be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss
1718be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss/* Default window configuration entry to use (see windows[]) */
1728be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss#define DEFAULT_WINDOW_INDEX	2
1738be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss
174f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/********************************************************************/
175f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1768be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Laussstatic struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
177f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
1788be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Laussstatic int device_count = MAX_DEVICE_COUNT;
1798be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Laussstatic int window_index = DEFAULT_WINDOW_INDEX;	/* default is zero */
180f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int panel_index = 2; /* default is zero */
181f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct window_settings *win;
182f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct panel_settings *panel;
183f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int noblanking = 1;
184f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int nohwcursor = 0;
185f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
186f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestruct window_settings {
187f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned char name[64];
188f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_backcolor;
189f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_colorkey;
190f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_colorkeymsk;
191f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct {
192f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		int xres;
193f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		int yres;
194f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		int xpos;
195f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		int ypos;
196f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
197f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		uint32 mode_winenable;
198f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	} w[4];
199f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
200f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
201f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if defined(__BIG_ENDIAN)
202f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
203f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#else
204f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
205f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
206f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
207f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*
208f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Default window configurations
209f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
210f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct window_settings windows[] = {
211f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	{ /* Index 0 */
212f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		"0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
213f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mode_backcolor	*/ 0x006600ff,
214f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mode_colorkey,msk*/ 0, 0,
215f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{
216f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
217f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
218f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
219f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP,
220f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ LCD_WINENABLE_WEN0,
221f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
222f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
223f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 100, 100, 100, 100,
224f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
225f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP |
226f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PIPE,
227f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ LCD_WINENABLE_WEN1,
228f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
229f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
230f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
231f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
232f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP,
233f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0,
234f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
235f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
236f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
237f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
238f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP |
239f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PIPE,
240f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0,
241f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
242f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
243f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
244f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
245f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	{ /* Index 1 */
246f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		"0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
247f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mode_backcolor	*/ 0x006600ff,
248f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mode_colorkey,msk*/ 0, 0,
249f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{
250f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
251f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 320, 240, 5, 5,
252f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
253f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_00,
254f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ LCD_WINENABLE_WEN0,
255f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
256f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
257f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
258f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
259f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				| LCD_WINCTRL1_PO_16BPP,
260f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0,
261f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
262f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
263f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 100, 100, 0, 0,
264f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
265f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP |
266f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PIPE,
267f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
268f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
269f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
270f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 200, 25, 0, 0,
271f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
272f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP |
273f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PIPE,
274f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0,
275f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
276f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
277f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
278f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	{ /* Index 2 */
279f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		"0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
280f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mode_backcolor	*/ 0x006600ff,
281f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mode_colorkey,msk*/ 0, 0,
282f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{
283f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
284f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
285f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
286f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP,
287f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ LCD_WINENABLE_WEN0,
288f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
289f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
290f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
291f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
292f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP,
293f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0,
294f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
295f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
296f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
297f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
298f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
299f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
300f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
301f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
302f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* xres, yres, xpos, ypos */ 0, 0, 0, 0,
303f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
304f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PO_16BPP |
305f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_PIPE,
306f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* mode_winenable*/ 0,
307f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			},
308f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
309f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
310f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Need VGA 640 @ 24bpp, @ 32bpp */
311f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Need VGA 800 @ 24bpp, @ 32bpp */
312f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Need VGA 1024 @ 24bpp, @ 32bpp */
313f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
314f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
315f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*
316f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Controller configurations for various panels.
317f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
318f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
319f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestruct panel_settings
320f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
321f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	const char name[25];		/* Full name <vendor>_<model> */
322f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
323f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct 	fb_monspecs monspecs; 	/* FB monitor specs */
324f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
325f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* panel timings */
326f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_screen;
327f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_horztiming;
328f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_verttiming;
329f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_clkcontrol;
330f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_pwmdiv;
331f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_pwmhi;
332f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_outmask;
333f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_fifoctrl;
334f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 mode_backlight;
335ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss	uint32 lcdclk;
336f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define Xres min_xres
337f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define Yres min_yres
338f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	u32	min_xres;		/* Minimum horizontal resolution */
339f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	u32	max_xres;		/* Maximum horizontal resolution */
340f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	u32 	min_yres;		/* Minimum vertical resolution */
341f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	u32 	max_yres;		/* Maximum vertical resolution */
342f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
343f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
344f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/********************************************************************/
345f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
346f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
347f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* List of panels known to work with the AU1200 LCD controller.
348f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * To add a new panel, enter the same specifications as the
349f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Generic_TFT one, and MAKE SURE that it doesn't conflicts
350f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * with the controller restrictions. Restrictions are:
351f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle *
352f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * STN color panels: max_bpp <= 12
353f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * STN mono panels: max_bpp <= 4
354f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * TFT panels: max_bpp <= 16
355f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * max_xres <= 800
356f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * max_yres <= 600
357f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
358f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct panel_settings known_lcd_panels[] =
359f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
360f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
361f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "QVGA_320x240",
362f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
363f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
364f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
365f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
366f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
367f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
368f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
369f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
370f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
371f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
372f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
373f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= LCD_SCREEN_SX_N(320) |
374f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_SCREEN_SY_N(240),
375f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= 0x00c4623b,
376f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= 0x00502814,
377f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x00020002, /* /4=24Mhz */
378f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x00000000,
379f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x00000000,
380f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00FFFFFF,
381f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
382f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
383ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96,
384f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		320, 320,
385f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		240, 240,
386f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
387f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
388f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
389f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "VGA_640x480",
390f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
391f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
392f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
393f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
394f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
395f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
396f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
397f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
398f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
399f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
400f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
401f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= 0x13f9df80,
402f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= 0x003c5859,
403f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= 0x00741201,
404f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x00020001, /* /4=24Mhz */
405f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x00000000,
406f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x00000000,
407f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00FFFFFF,
408f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
409f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
410ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96,
411f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		640, 480,
412f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		640, 480,
413f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
414f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
415f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
416f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "SVGA_800x600",
417f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
418f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
419f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
420f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
421f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
422f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
423f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
424f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
425f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
426f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
427f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
428f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= 0x18fa5780,
429f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= 0x00dc7e77,
430f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= 0x00584805,
431f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x00020000, /* /2=48Mhz */
432f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x00000000,
433f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x00000000,
434f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00FFFFFF,
435f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
436f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
437ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96,
438f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		800, 800,
439f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		600, 600,
440f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
441f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
442f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
443f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "XVGA_1024x768",
444f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
445f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
446f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
447f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
448f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
449f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
450f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
451f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
452f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
453f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
454f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
455f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= 0x1ffaff80,
456f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= 0x007d0e57,
457f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= 0x00740a01,
458f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x000A0000, /* /1 */
459f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x00000000,
460f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x00000000,
461f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00FFFFFF,
462f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
463f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
464ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 72,
465f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		1024, 1024,
466f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		768, 768,
467f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
468f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
469f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
470f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "XVGA_1280x1024",
471f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
472f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
473f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
474f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
475f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
476f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
477f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
478f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
479f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
480f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
481f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
482f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= 0x27fbff80,
483f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= 0x00cdb2c7,
484f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= 0x00600002,
485f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x000A0000, /* /1 */
486f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x00000000,
487f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x00000000,
488f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00FFFFFF,
489f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
490f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
491ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 120,
492f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		1280, 1280,
493f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		1024, 1024,
494f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
495f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
496f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[5] = { /* Samsung 1024x768 TFT */
497f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "Samsung_1024x768_TFT",
498f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
499f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
500f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
501f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
502f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
503f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
504f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
505f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
506f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
507f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
508f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
509f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= 0x1ffaff80,
510f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= 0x018cc677,
511f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= 0x00241217,
512f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x00000000, /* SCB 0x1 /4=24Mhz */
513f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x8000063f, /* SCB 0x0 */
514f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x03400000, /* SCB 0x0 */
515f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00FFFFFF,
516f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
517f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
518ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96,
519f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		1024, 1024,
520f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		768, 768,
521f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
522f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
523f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[6] = { /* Toshiba 640x480 TFT */
524f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "Toshiba_640x480_TFT",
525f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
526f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
527f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
528f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
529f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
530f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
531f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
532f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
533f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
534f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
535f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
536f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= LCD_SCREEN_SX_N(640) |
537f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_SCREEN_SY_N(480),
538f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= LCD_HORZTIMING_HPW_N(96) |
539f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
540f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= LCD_VERTTIMING_VPW_N(2) |
541f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
542f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x00000000, /* /4=24Mhz */
543f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x8000063f,
544f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x03400000,
545f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00fcfcfc,
546f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
547f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
548ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96,
549f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		640, 480,
550f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		640, 480,
551f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
552f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
553f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[7] = { /* Sharp 320x240 TFT */
554f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "Sharp_320x240_TFT",
555f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
556f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
557f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
558f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 12500,
559f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 20000,
560f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 38,
561f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 81,
562f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 4500000,
563f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 6800000,
564f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
565f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
566f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= LCD_SCREEN_SX_N(320) |
567f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_SCREEN_SY_N(240),
568f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= LCD_HORZTIMING_HPW_N(60) |
569f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
570f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= LCD_VERTTIMING_VPW_N(2) |
571f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
572f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
573f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x8000063f,
574f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x03400000,
575f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00fcfcfc,
576f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
577f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
578ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96, /* 96MHz AUXPLL */
579f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		320, 320,
580f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		240, 240,
581f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
582f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
583f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
584f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.name = "Toppoly_TD070WGCB2",
585f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.monspecs = {
586f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb = NULL,
587f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.modedb_len = 0,
588f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmin = 30000,
589f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.hfmax = 70000,
590f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmin = 60,
591f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.vfmax = 60,
592f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmin = 6000000,
593f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.dclkmax = 28000000,
594f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			.input = FB_DISP_RGB,
595f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		},
596f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_screen		= LCD_SCREEN_SX_N(856) |
597f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_SCREEN_SY_N(480),
598f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_horztiming	= LCD_HORZTIMING_HND2_N(43) |
599f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
600f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_verttiming	= LCD_VERTTIMING_VND2_N(20) |
601f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
602f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_clkcontrol	= 0x00020001, /* /4=24Mhz */
603f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmdiv		= 0x8000063f,
604f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_pwmhi		= 0x03400000,
605f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_outmask	= 0x00fcfcfc,
606f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_fifoctrl	= 0x2f2f2f2f,
607f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		.mode_backlight	= 0x00000000,
608ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk		= 96,
609f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		856, 856,
610f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		480, 480,
611f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	},
61264cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss	[9] = {
61364cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.name = "DB1300_800x480",
61464cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.monspecs = {
61564cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.modedb = NULL,
61664cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.modedb_len = 0,
61764cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.hfmin = 30000,
61864cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.hfmax = 70000,
61964cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.vfmin = 60,
62064cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.vfmax = 60,
62164cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.dclkmin = 6000000,
62264cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.dclkmax = 28000000,
62364cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss			.input = FB_DISP_RGB,
62464cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		},
62564cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_screen		= LCD_SCREEN_SX_N(800) |
62664cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_SCREEN_SY_N(480),
62764cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_horztiming	= LCD_HORZTIMING_HPW_N(5) |
62864cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_HORZTIMING_HND1_N(16) |
62964cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_HORZTIMING_HND2_N(8),
63064cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_verttiming	= LCD_VERTTIMING_VPW_N(4) |
63164cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_VERTTIMING_VND1_N(8) |
63264cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_VERTTIMING_VND2_N(5),
63364cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_clkcontrol	= LCD_CLKCONTROL_PCD_N(1) |
63464cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_CLKCONTROL_IV |
63564cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss					  LCD_CLKCONTROL_IH,
63664cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_pwmdiv		= 0x00000000,
63764cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_pwmhi		= 0x00000000,
63864cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_outmask		= 0x00FFFFFF,
63964cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_fifoctrl		= 0x2f2f2f2f,
64064cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		.mode_backlight		= 0x00000000,
641ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		.lcdclk			= 96,
64264cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		800, 800,
64364cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss		480, 480,
64464cd04d0cffa3b3af0e81aa3112b71f135739e1aManuel Lauss	},
645f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
646f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
647f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
648f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
649f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/********************************************************************/
650f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
651f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int winbpp (unsigned int winctrl1)
652f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
653f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int bits = 0;
654f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
655f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* how many bits are needed for each pixel format */
656f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	switch (winctrl1 & LCD_WINCTRL1_FRM) {
657f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_1BPP:
658f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bits = 1;
659f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
660f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_2BPP:
661f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bits = 2;
662f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
663f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_4BPP:
664f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bits = 4;
665f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
666f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_8BPP:
667f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bits = 8;
668f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
669f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_12BPP:
670f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPP655:
671f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPP565:
672f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPP556:
673f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPPI1555:
674f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPPI5551:
675f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPPA1555:
676f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_16BPPA5551:
677f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bits = 16;
678f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
679f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_24BPP:
680f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case LCD_WINCTRL1_FRM_32BPP:
681f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bits = 32;
682f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
683f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
684f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
685f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return bits;
686f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
687f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
688f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int fbinfo2index (struct fb_info *fb_info)
689f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
690f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int i;
691f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
6928be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss	for (i = 0; i < device_count; ++i) {
693c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		if (fb_info == _au1200fb_infos[i])
694f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return i;
695f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
696f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	printk("au1200fb: ERROR: fbinfo2index failed!\n");
697f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return -1;
698f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
699f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
700f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
701f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int xpos, int ypos)
702f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
703f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
704f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int xsz, ysz;
705f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
706f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
707f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
708f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl0 = lcd->window[plane].winctrl0;
709f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl1 = lcd->window[plane].winctrl1;
710f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
711f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
712f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
713f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Check for off-screen adjustments */
714f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	xsz = win->w[plane].xres;
715f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	ysz = win->w[plane].yres;
716f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if ((xpos + win->w[plane].xres) > panel->Xres) {
717f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Off-screen to the right */
718f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		xsz = panel->Xres - xpos; /* off by 1 ??? */
719f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/*printk("off screen right\n");*/
720f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
721f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
722f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if ((ypos + win->w[plane].yres) > panel->Yres) {
723f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Off-screen to the bottom */
724f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		ysz = panel->Yres - ypos; /* off by 1 ??? */
725f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/*printk("off screen bottom\n");*/
726f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
727f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
728f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (xpos < 0) {
729f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Off-screen to the left */
730f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		xsz = win->w[plane].xres + xpos;
731f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
732f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		xpos = 0;
733f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/*printk("off screen left\n");*/
734f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
735f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
736f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (ypos < 0) {
737f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Off-screen to the top */
738f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		ysz = win->w[plane].yres + ypos;
739f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
740f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		ypos = 0;
741f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/*printk("off screen top\n");*/
742f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
743f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
744f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* record settings */
745f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	win->w[plane].xpos = xpos;
746f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	win->w[plane].ypos = ypos;
747f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
748f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	xsz -= 1;
749f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	ysz -= 1;
750f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl0 |= (xpos << 21);
751f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl0 |= (ypos << 10);
752f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl1 |= (xsz << 11);
753f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winctrl1 |= (ysz << 0);
754f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
755f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Disable the window while making changes, then restore WINEN */
756f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winenable = lcd->winenable & (1 << plane);
7572f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
758f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->winenable &= ~(1 << plane);
759f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winctrl0 = winctrl0;
760f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winctrl1 = winctrl1;
761f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winbuf0 =
762f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winbuf1 = fbdev->fb_phys;
763f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
764f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->winenable |= winenable;
7652f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
766f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
767f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
768f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
769f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
770a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Laussstatic void au1200_setpanel(struct panel_settings *newpanel,
771a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			    struct au1200fb_platdata *pd)
772f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
773f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/*
774f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * Perform global setup/init of LCD controller
775f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 */
776f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	uint32 winenable;
777f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
778f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Make sure all windows disabled */
779f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	winenable = lcd->winenable;
780f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->winenable = 0;
7812f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
782f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/*
783f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * Ensure everything is disabled before reconfiguring
784f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 */
785f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (lcd->screen & LCD_SCREEN_SEN) {
786f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Wait for vertical sync period */
787f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->intstatus = LCD_INT_SS;
7882f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss		while ((lcd->intstatus & LCD_INT_SS) == 0)
7892f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss			;
790f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
791f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->screen &= ~LCD_SCREEN_SEN;	/*disable the controller*/
792f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
793f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		do {
794f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			lcd->intstatus = lcd->intstatus; /*clear interrupts*/
7952f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss			wmb(); /* drain writebuffer */
796f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/*wait for controller to shut down*/
797f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		} while ((lcd->intstatus & LCD_INT_SD) == 0);
798f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
799f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Call shutdown of current panel (if up) */
800f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* this must occur last, because if an external clock is driving
801f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		    the controller, the clock cannot be turned off before first
802f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			shutting down the controller.
803f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		 */
804a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		if (pd->panel_shutdown)
805a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			pd->panel_shutdown();
806f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
807f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
808f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Newpanel == NULL indicates a shutdown operation only */
809f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (newpanel == NULL)
810f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return;
811f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
812f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	panel = newpanel;
813f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
814f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
815f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
816f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/*
817f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
818f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 */
819f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
820f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	{
821ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		struct clk *c = clk_get(NULL, "lcd_intclk");
822ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		long r, pc = panel->lcdclk * 1000000;
823ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss
824ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		if (!IS_ERR(c)) {
825ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss			r = clk_round_rate(c, pc);
826ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss			if ((pc - r) < (pc / 10)) {	/* 10% slack */
827ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss				clk_set_rate(c, r);
828ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss				clk_prepare_enable(c);
829ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss			}
830ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss			clk_put(c);
831ecc2ea3bd887188a1cc7702b1b52633ed91eb941Manuel Lauss		}
832f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
833f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
834f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/*
835f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * Configure panel timings
836f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 */
837f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->screen = panel->mode_screen;
838f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->horztiming = panel->mode_horztiming;
839f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->verttiming = panel->mode_verttiming;
840f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->clkcontrol = panel->mode_clkcontrol;
841f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->pwmdiv = panel->mode_pwmdiv;
842f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->pwmhi = panel->mode_pwmhi;
843f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->outmask = panel->mode_outmask;
844f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->fifoctrl = panel->mode_fifoctrl;
8452f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
846f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
847f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* fixme: Check window settings to make sure still valid
848f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * for new geometry */
849f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if 0
850f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
851f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
852f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
853f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
854f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
855f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->winenable = winenable;
856f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
857f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/*
858f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * Re-enable screen now that it is configured
859f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 */
860f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->screen |= LCD_SCREEN_SEN;
8612f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
862f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
863f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Call init of panel */
864a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	if (pd->panel_init)
865a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		pd->panel_init();
866f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
867f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* FIX!!!! not appropriate on panel change!!! Global setup/init */
868f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->intenable = 0;
869f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->intstatus = ~0;
870f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->backcolor = win->mode_backcolor;
871f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
872f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Setup Color Key - FIX!!! */
873f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->colorkey = win->mode_colorkey;
874f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->colorkeymsk = win->mode_colorkeymsk;
875f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
876f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Setup HWCursor - FIX!!! Need to support this eventually */
877f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->hwc.cursorctrl = 0;
878f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->hwc.cursorpos = 0;
879f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->hwc.cursorcolor0 = 0;
880f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->hwc.cursorcolor1 = 0;
881f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->hwc.cursorcolor2 = 0;
882f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->hwc.cursorcolor3 = 0;
883f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
884f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
885f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if 0
886f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define D(X) printk("%25s: %08X\n", #X, X)
887f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->screen);
888f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->horztiming);
889f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->verttiming);
890f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->clkcontrol);
891f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->pwmdiv);
892f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->pwmhi);
893f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->outmask);
894f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->fifoctrl);
895f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[0].winctrl0);
896f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[0].winctrl1);
897f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[0].winctrl2);
898f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[0].winbuf0);
899f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[0].winbuf1);
900f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[0].winbufctrl);
901f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[1].winctrl0);
902f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[1].winctrl1);
903f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[1].winctrl2);
904f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[1].winbuf0);
905f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[1].winbuf1);
906f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[1].winbufctrl);
907f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[2].winctrl0);
908f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[2].winctrl1);
909f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[2].winctrl2);
910f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[2].winbuf0);
911f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[2].winbuf1);
912f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[2].winbufctrl);
913f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[3].winctrl0);
914f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[3].winctrl1);
915f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[3].winctrl2);
916f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[3].winbuf0);
917f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[3].winbuf1);
918f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->window[3].winbufctrl);
919f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->winenable);
920f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->intenable);
921f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->intstatus);
922f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->backcolor);
923f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->winenable);
924f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->colorkey);
925f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle    D(lcd->colorkeymsk);
926f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->hwc.cursorctrl);
927f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->hwc.cursorpos);
928f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->hwc.cursorcolor0);
929f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->hwc.cursorcolor1);
930f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->hwc.cursorcolor2);
931f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	D(lcd->hwc.cursorcolor3);
932f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
933f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
934f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
935f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic void au1200_setmode(struct au1200fb_device *fbdev)
936f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
937f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int plane = fbdev->plane;
938f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window/plane setup */
939f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winctrl1 = ( 0
940f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		| LCD_WINCTRL1_PRI_N(plane)
941f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		| win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
942f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		) ;
943f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
944f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
945f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
946f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->window[plane].winctrl2 = ( 0
947f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		| LCD_WINCTRL2_CKMODE_00
948f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		| LCD_WINCTRL2_DBM
949c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		| LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
950f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		| LCD_WINCTRL2_SCX_1
951f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		| LCD_WINCTRL2_SCY_1
952f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		) ;
953f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->winenable |= win->w[plane].mode_winenable;
9542f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
955f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
956f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
957f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
958f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* Inline helpers */
959f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
960f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*#define panel_is_dual(panel)  ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
961f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
962f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
963f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
964f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
965f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* Bitfields format supported by the controller. */
966f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct fb_bitfield rgb_bitfields[][4] = {
967f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle  	/*     Red, 	   Green, 	 Blue, 	     Transp   */
968f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPP655 >> 25] =
969f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
970f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
971f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPP565 >> 25] =
972f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
973f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
974f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPP556 >> 25] =
975f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
976f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
977f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
978f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
979f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
980f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
981f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
982f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
983f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
984f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
985f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
986f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
987f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
988f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
989f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_24BPP >> 25] =
990f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
991f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
992f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	[LCD_WINCTRL1_FRM_32BPP >> 25] =
993f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{ { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
994f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
995f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
996f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*-------------------------------------------------------------------------*/
997f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
998f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* Helpers */
999f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1000f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic void au1200fb_update_fbinfo(struct fb_info *fbi)
1001f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1002f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* FIX!!!! This also needs to take the window pixel format into account!!! */
1003f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1004f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Update var-dependent FB info */
1005f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (panel_is_color(panel)) {
1006f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (fbi->var.bits_per_pixel <= 8) {
1007f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* palettized */
1008f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1009f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			fbi->fix.line_length = fbi->var.xres_virtual /
1010f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				(8/fbi->var.bits_per_pixel);
1011f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		} else {
1012f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* non-palettized */
1013f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			fbi->fix.visual = FB_VISUAL_TRUECOLOR;
1014f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
1015f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1016f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	} else {
1017f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* mono FIX!!! mono 8 and 4 bits */
1018f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		fbi->fix.visual = FB_VISUAL_MONO10;
1019f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		fbi->fix.line_length = fbi->var.xres_virtual / 8;
1020f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1021f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1022f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
1023f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	print_dbg("line length: %d\n", fbi->fix.line_length);
1024f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
1025f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1026f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1027f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*-------------------------------------------------------------------------*/
1028f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1029f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* AU1200 framebuffer driver */
1030f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1031f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* fb_check_var
1032f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Validate var settings with hardware restrictions and modify it if necessary
1033f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
1034f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
1035f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct fb_info *fbi)
1036f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1037c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct au1200fb_device *fbdev = fbi->par;
1038f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	u32 pixclock;
1039f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int screen_size, plane;
1040f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1041f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	plane = fbdev->plane;
1042f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1043f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Make sure that the mode respect all LCD controller and
1044f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * panel restrictions. */
1045f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	var->xres = win->w[plane].xres;
1046f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	var->yres = win->w[plane].yres;
1047f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1048f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* No need for virtual resolution support */
1049f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	var->xres_virtual = var->xres;
1050f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	var->yres_virtual = var->yres;
1051f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1052f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
1053f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1054f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	screen_size = var->xres_virtual * var->yres_virtual;
1055f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
1056f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	else screen_size /= (8/var->bits_per_pixel);
1057f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1058f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (fbdev->fb_len < screen_size)
1059f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return -EINVAL; /* Virtual screen is to big, abort */
1060f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1061f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
1062f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
1063f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * clock can only be obtain by dividing this value by an even integer.
1064f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * Fallback to a slower pixel clock if necessary. */
1065f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
1066732eacc0542d0aa48797f675888b85d6065af837Hagen Paul Pfeifer	pixclock = min3(pixclock, fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2);
1067f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1068f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (AU1200_LCD_MAX_CLK % pixclock) {
1069f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		int diff = AU1200_LCD_MAX_CLK % pixclock;
1070f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		pixclock -= diff;
1071f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1072f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1073f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	var->pixclock = KHZ2PICOS(pixclock/1000);
1074f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if 0
1075f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (!panel_is_active(panel)) {
1076f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
1077f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1078f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (!panel_is_color(panel)
1079f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			&& (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
1080f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* STN 8bit mono panel support is up to 6MHz pixclock */
1081f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->pixclock = KHZ2PICOS(6000);
1082f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		} else if (!pcd) {
1083f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* Other STN panel support is up to 12MHz  */
1084f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->pixclock = KHZ2PICOS(12000);
1085f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1086f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1087f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
1088f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Set bitfield accordingly */
1089f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	switch (var->bits_per_pixel) {
1090f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case 16:
1091f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{
1092f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* 16bpp True color.
1093f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			 * These must be set to MATCH WINCTRL[FORM] */
1094f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			int idx;
1095f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1096f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->red    = rgb_bitfields[idx][0];
1097f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->green  = rgb_bitfields[idx][1];
1098f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->blue   = rgb_bitfields[idx][2];
1099f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->transp = rgb_bitfields[idx][3];
1100f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1101f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1102f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1103f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case 32:
1104f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		{
1105f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			/* 32bpp True color.
1106f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			 * These must be set to MATCH WINCTRL[FORM] */
1107f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			int idx;
1108f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1109f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->red    = rgb_bitfields[idx][0];
1110f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->green  = rgb_bitfields[idx][1];
1111f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->blue   = rgb_bitfields[idx][2];
1112f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			var->transp = rgb_bitfields[idx][3];
1113f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1114f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1115f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		default:
1116f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
1117f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return -EINVAL;
1118f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1119f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1120f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1121f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1122f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1123f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* fb_set_par
1124f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Set hardware with var settings. This will enable the controller with a
1125f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * specific mode, normally validated with the fb_check_var method
1126f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
1127f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_fb_set_par(struct fb_info *fbi)
1128f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1129c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct au1200fb_device *fbdev = fbi->par;
1130f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1131f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200fb_update_fbinfo(fbi);
1132f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200_setmode(fbdev);
1133f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1134f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1135f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1136f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1137f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* fb_setcolreg
1138f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Set color in LCD palette.
1139f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
1140f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
1141f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned blue, unsigned transp, struct fb_info *fbi)
1142f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1143f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	volatile u32 *palette = lcd->palette;
1144f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	u32 value;
1145f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1146f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
1147f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return -EINVAL;
1148f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1149f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (fbi->var.grayscale) {
1150f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Convert color to grayscale */
1151f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		red = green = blue =
1152f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			(19595 * red + 38470 * green + 7471 * blue) >> 16;
1153f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1154f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1155f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
1156f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Place color in the pseudopalette */
1157f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (regno > 16)
1158f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return -EINVAL;
1159f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1160f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		palette = (u32*) fbi->pseudo_palette;
1161f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1162f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		red   >>= (16 - fbi->var.red.length);
1163f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		green >>= (16 - fbi->var.green.length);
1164f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		blue  >>= (16 - fbi->var.blue.length);
1165f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1166f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value = (red   << fbi->var.red.offset) 	|
1167f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			(green << fbi->var.green.offset)|
1168f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			(blue  << fbi->var.blue.offset);
1169f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value &= 0xFFFF;
1170f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1171f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	} else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
1172f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* COLOR TFT PALLETTIZED (use RGB 565) */
1173f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value = (red & 0xF800)|((green >> 5) &
1174f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				0x07E0)|((blue >> 11) & 0x001F);
1175f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value &= 0xFFFF;
1176f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1177f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	} else if (0 /*panel_is_color(fbdev->panel)*/) {
1178f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* COLOR STN MODE */
1179f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value = 0x1234;
1180f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value &= 0xFFF;
1181f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	} else {
1182f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* MONOCHROME MODE */
1183f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value = (green >> 12) & 0x000F;
1184f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		value &= 0xF;
1185f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1186f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1187f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	palette[regno] = value;
1188f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1189f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1190f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1191f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1192f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* fb_blank
1193f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Blank the screen. Depending on the mode, the screen will be
1194f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * activated with the backlight color, or desactivated
1195f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
1196f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
1197f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1198a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_device *fbdev = fbi->par;
1199a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1200f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Short-circuit screen blanking */
1201f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (noblanking)
1202f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return 0;
1203f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1204f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	switch (blank_mode) {
1205f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1206f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case FB_BLANK_UNBLANK:
1207f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case FB_BLANK_NORMAL:
1208f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* printk("turn on panel\n"); */
1209a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		au1200_setpanel(panel, fbdev->pd);
1210f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
1211f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case FB_BLANK_VSYNC_SUSPEND:
1212f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case FB_BLANK_HSYNC_SUSPEND:
1213f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	case FB_BLANK_POWERDOWN:
1214f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* printk("turn off panel\n"); */
1215a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		au1200_setpanel(NULL, fbdev->pd);
1216f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
1217f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	default:
1218f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		break;
1219f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1220f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1221f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1222f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* FB_BLANK_NORMAL is a soft blank */
1223f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
1224f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1225f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1226f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* fb_mmap
1227f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * Map video memory in user space. We don't use the generic fb_mmap
1228f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle * method mainly to allow the use of the TLB streaming flag (CCA=6)
1229f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle */
1230f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1231f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1232c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct au1200fb_device *fbdev = info->par;
1233f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1234f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1235f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
1236f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
12377314e613d5ff9f0934f7a0f74ed7973b903315d1Linus Torvalds	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
1238f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1239f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1240f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
1241f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1242f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1243f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int hi1, divider;
1244f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1245f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* SCREEN_SIZE: user cannot reset size, must switch panel choice */
1246f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1247f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & SCREEN_BACKCOLOR)
1248f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->backcolor = pdata->backcolor;
1249f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1250f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & SCREEN_BRIGHTNESS) {
1251f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1252f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		// limit brightness pwm duty to >= 30/1600
1253f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (pdata->brightness < 30) {
1254f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			pdata->brightness = 30;
1255f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1256f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		divider = (lcd->pwmdiv & 0x3FFFF) + 1;
1257f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
1258f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->pwmhi &= 0xFFFF;
1259f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->pwmhi |= (hi1 << 16);
1260f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1261f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1262f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & SCREEN_COLORKEY)
1263f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->colorkey = pdata->colorkey;
1264f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1265f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & SCREEN_MASK)
1266f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->colorkeymsk = pdata->mask;
12672f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
1268f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1269f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1270f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
1271f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1272f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int hi1, divider;
1273f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1274f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
1275f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
1276f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1277f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->backcolor = lcd->backcolor;
1278f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->colorkey = lcd->colorkey;
1279f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->mask = lcd->colorkeymsk;
1280f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1281f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	// brightness
1282f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	hi1 = (lcd->pwmhi >> 16) + 1;
1283f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	divider = (lcd->pwmdiv & 0x3FFFF) + 1;
1284f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->brightness = ((hi1 << 8) / divider) - 1;
12852f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
1286f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1287f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1288f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic void set_window(unsigned int plane,
1289f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct au1200_lcd_window_regs_t *pdata)
1290f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1291f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned int val, bpp;
1292f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1293f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window control register 0 */
1294f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_POSITION) {
1295f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
1296f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL0_OY);
1297f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
1298f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
1299f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl0 = val;
1300f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1301f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_ALPHA_COLOR) {
1302f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
1303f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
1304f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl0 = val;
1305f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1306f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_ALPHA_MODE) {
1307f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
1308f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
1309f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl0 = val;
1310f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1311f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1312f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window control register 1 */
1313f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_PRIORITY) {
1314f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
1315f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
1316f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl1 = val;
1317f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1318f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_CHANNEL) {
1319f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
1320f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
1321f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl1 = val;
1322f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1323f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_BUFFER_FORMAT) {
1324f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
1325f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
1326f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl1 = val;
1327f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1328f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_COLOR_ORDER) {
1329f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
1330f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
1331f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl1 = val;
1332f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1333f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_PIXEL_ORDER) {
1334f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
1335f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
1336f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl1 = val;
1337f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1338f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_SIZE) {
1339f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
1340f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL1_SZY);
1341f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
1342f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
1343f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl1 = val;
1344f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* program buffer line width */
1345f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bpp = winbpp(val) / 8;
1346f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
1347f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
1348f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl2 = val;
1349f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1350f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1351f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window control register 2 */
1352f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_COLORKEY_MODE) {
1353f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
1354f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
1355f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl2 = val;
1356f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1357f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
1358f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
1359f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
1360f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl2 = val;
1361f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1362f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_RAM_ARRAY_MODE) {
1363f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
1364f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
1365f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl2 = val;
1366f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1367f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1368f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Buffer line width programmed with WIN_SIZE */
1369f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1370f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_BUFFER_SCALE) {
1371f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
1372f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				LCD_WINCTRL2_SCY);
1373f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
1374f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
1375f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->window[plane].winctrl2 = val;
1376f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1377f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1378f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (pdata->flags & WIN_ENABLE) {
1379f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = lcd->winenable;
1380f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val &= ~(1<<plane);
1381f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val |= (pdata->enable & 1) << plane;
1382f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		lcd->winenable = val;
1383f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
13842f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
1385f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1386f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1387f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic void get_window(unsigned int plane,
1388f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct au1200_lcd_window_regs_t *pdata)
1389f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1390f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window control register 0 */
1391f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
1392f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
1393f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
1394f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
1395f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1396f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window control register 1 */
1397f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
1398f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
1399f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
1400f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
1401f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
1402f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
1403f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
1404f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1405f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Window control register 2 */
1406f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
1407f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
1408f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
1409f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1410f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	pdata->enable = (lcd->winenable >> plane) & 1;
14112f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
1412f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1413f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1414f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
1415f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle                          unsigned long arg)
1416f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1417a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_device *fbdev = info->par;
1418f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int plane;
1419f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int val;
1420f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1421f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	plane = fbinfo2index(info);
1422f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
1423f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1424f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (cmd == AU1200_LCD_FB_IOCTL) {
1425f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		struct au1200_lcd_iodata_t iodata;
1426f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1427f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
1428f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return -EFAULT;
1429f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1430f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		print_dbg("FB IOCTL called\n");
1431f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1432f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		switch (iodata.subcmd) {
1433f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case AU1200_LCD_SET_SCREEN:
1434f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("AU1200_LCD_SET_SCREEN\n");
1435f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			set_global(cmd, &iodata.global);
1436f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1437f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1438f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case AU1200_LCD_GET_SCREEN:
1439f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("AU1200_LCD_GET_SCREEN\n");
1440f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			get_global(cmd, &iodata.global);
1441f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1442f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1443f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case AU1200_LCD_SET_WINDOW:
1444f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("AU1200_LCD_SET_WINDOW\n");
1445f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			set_window(plane, &iodata.window);
1446f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1447f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1448f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case AU1200_LCD_GET_WINDOW:
1449f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("AU1200_LCD_GET_WINDOW\n");
1450f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			get_window(plane, &iodata.window);
1451f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1452f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1453f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case AU1200_LCD_SET_PANEL:
1454f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("AU1200_LCD_SET_PANEL\n");
1455f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			if ((iodata.global.panel_choice >= 0) &&
1456f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle					(iodata.global.panel_choice <
1457f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle					 NUM_PANELS))
1458f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			{
1459f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				struct panel_settings *newpanel;
1460f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				panel_index = iodata.global.panel_choice;
1461f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				newpanel = &known_lcd_panels[panel_index];
1462a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				au1200_setpanel(newpanel, fbdev->pd);
1463f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			}
1464f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1465f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1466f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		case AU1200_LCD_GET_PANEL:
1467f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("AU1200_LCD_GET_PANEL\n");
1468f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			iodata.global.panel_choice = panel_index;
1469f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			break;
1470f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1471f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		default:
1472f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return -EINVAL;
1473f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1474f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1475f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
1476f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (val) {
1477f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_dbg("error: could not copy %d bytes\n", val);
1478f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return -EFAULT;
1479f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1480f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1481f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1482f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1483f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1484f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1485f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1486f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic struct fb_ops au1200fb_fb_ops = {
1487f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.owner		= THIS_MODULE,
1488f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_check_var	= au1200fb_fb_check_var,
1489f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_set_par	= au1200fb_fb_set_par,
1490f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_setcolreg	= au1200fb_fb_setcolreg,
1491f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_blank	= au1200fb_fb_blank,
14924ee58461510221a53080afd02752838f93cc57fcManuel Lauss	.fb_fillrect	= sys_fillrect,
14934ee58461510221a53080afd02752838f93cc57fcManuel Lauss	.fb_copyarea	= sys_copyarea,
14944ee58461510221a53080afd02752838f93cc57fcManuel Lauss	.fb_imageblit	= sys_imageblit,
14954ee58461510221a53080afd02752838f93cc57fcManuel Lauss	.fb_read	= fb_sys_read,
14964ee58461510221a53080afd02752838f93cc57fcManuel Lauss	.fb_write	= fb_sys_write,
1497f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_sync	= NULL,
1498f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_ioctl	= au1200fb_ioctl,
1499f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.fb_mmap	= au1200fb_fb_mmap,
1500f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
1501f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1502f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*-------------------------------------------------------------------------*/
1503f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
15047d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
1505f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1506f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Nothing to do for now, just clear any pending interrupt */
1507f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	lcd->intstatus = lcd->intstatus;
15082f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
1509f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1510f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return IRQ_HANDLED;
1511f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1512f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1513f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*-------------------------------------------------------------------------*/
1514f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1515f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/* AU1200 LCD device probe helpers */
1516f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1517f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlestatic int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
1518f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1519c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct fb_info *fbi = fbdev->fb_info;
1520f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int bpp;
1521f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1522f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fbops = &au1200fb_fb_ops;
1523f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1524f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
1525f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1526f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Copy monitor specs from panel data */
1527f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* fixme: we're setting up LCD controller windows, so these dont give a
1528f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	damn as to what the monitor specs are (the panel itself does, but that
152925985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	isn't done here...so maybe need a generic catchall monitor setting??? */
1530f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
1531f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1532f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* We first try the user mode passed in argument. If that failed,
1533f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * or if no one has been specified, we default to the first mode of the
1534f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	 * panel list. Note that after this call, var data will be set */
1535f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (!fb_find_mode(&fbi->var,
1536f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			  fbi,
1537f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			  NULL, /* drv_info.opt_mode, */
1538f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			  fbi->monspecs.modedb,
1539f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			  fbi->monspecs.modedb_len,
1540f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			  fbi->monspecs.modedb,
1541f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			  bpp)) {
1542f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1543f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		print_err("Cannot find valid mode for panel %s", panel->name);
1544f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return -EFAULT;
1545f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1546f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1547dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau	fbi->pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL);
1548f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (!fbi->pseudo_palette) {
1549f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return -ENOMEM;
1550f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1551f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1552f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
1553f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		print_err("Fail to allocate colormap (%d entries)",
1554f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			   AU1200_LCD_NBR_PALETTE_ENTRIES);
1555f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		kfree(fbi->pseudo_palette);
1556f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		return -EFAULT;
1557f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1558f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1559f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
1560f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.smem_start = fbdev->fb_phys;
1561f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.smem_len = fbdev->fb_len;
1562f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.type = FB_TYPE_PACKED_PIXELS;
1563f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.xpanstep = 0;
1564f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.ypanstep = 0;
1565f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.mmio_start = 0;
1566f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.mmio_len = 0;
1567f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->fix.accel = FB_ACCEL_NONE;
1568f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1569f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	fbi->screen_base = (char __iomem *) fbdev->fb_mem;
1570f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1571f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	au1200fb_update_fbinfo(fbi);
1572f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1573f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1574f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1575f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1576f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle/*-------------------------------------------------------------------------*/
1577f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1578f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1579a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Laussstatic int au1200fb_setup(struct au1200fb_platdata *pd)
1580a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss{
1581a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	char *options = NULL;
1582a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	char *this_opt, *endptr;
1583a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	int num_panels = ARRAY_SIZE(known_lcd_panels);
1584a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	int panel_idx = -1;
1585a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1586a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	fb_get_options(DRIVER_NAME, &options);
1587a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1588a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	if (!options)
1589a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		goto out;
1590a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1591a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	while ((this_opt = strsep(&options, ",")) != NULL) {
1592a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		/* Panel option - can be panel name,
1593a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		 * "bs" for board-switch, or number/index */
1594a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		if (!strncmp(this_opt, "panel:", 6)) {
1595a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			int i;
1596a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			long int li;
1597a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			char *endptr;
1598a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			this_opt += 6;
1599a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			/* First check for index, which allows
1600a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			 * to short circuit this mess */
1601a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			li = simple_strtol(this_opt, &endptr, 0);
1602a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			if (*endptr == '\0')
1603a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				panel_idx = (int)li;
1604a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			else if (strcmp(this_opt, "bs") == 0)
1605a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				panel_idx = pd->panel_index();
1606a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			else {
1607a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				for (i = 0; i < num_panels; i++) {
1608a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss					if (!strcmp(this_opt,
1609a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss						    known_lcd_panels[i].name)) {
1610a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss						panel_idx = i;
1611a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss						break;
1612a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss					}
1613a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				}
1614a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			}
1615a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			if ((panel_idx < 0) || (panel_idx >= num_panels))
1616a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				print_warn("Panel %s not supported!", this_opt);
1617a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			else
1618a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				panel_index = panel_idx;
1619a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1620a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		} else if (strncmp(this_opt, "nohwcursor", 10) == 0)
1621a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			nohwcursor = 1;
1622a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		else if (strncmp(this_opt, "devices:", 8) == 0) {
1623a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			this_opt += 8;
1624a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			device_count = simple_strtol(this_opt, &endptr, 0);
1625a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			if ((device_count < 0) ||
1626a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			    (device_count > MAX_DEVICE_COUNT))
1627a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				device_count = MAX_DEVICE_COUNT;
1628a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		} else if (strncmp(this_opt, "wincfg:", 7) == 0) {
1629a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			this_opt += 7;
1630a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			window_index = simple_strtol(this_opt, &endptr, 0);
1631a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			if ((window_index < 0) ||
1632a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			    (window_index >= ARRAY_SIZE(windows)))
1633a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss				window_index = DEFAULT_WINDOW_INDEX;
1634a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		} else if (strncmp(this_opt, "off", 3) == 0)
1635a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			return 1;
1636a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		else
1637a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss			print_warn("Unsupported option \"%s\"", this_opt);
1638a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	}
1639a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1640a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Laussout:
1641a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	return 0;
1642a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss}
1643a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1644a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss/* AU1200 LCD controller device driver */
164548c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int au1200fb_drv_probe(struct platform_device *dev)
1646f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1647f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct au1200fb_device *fbdev;
1648a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_platdata *pd;
1649c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct fb_info *fbi = NULL;
1650f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	unsigned long page;
16511630d85a831273868651d46d74f069e0cdf9b698Manuel Lauss	int bpp, plane, ret, irq;
1652f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1653a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	print_info("" DRIVER_DESC "");
1654a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1655a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	pd = dev->dev.platform_data;
1656a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	if (!pd)
1657a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		return -ENODEV;
1658a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1659a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	/* Setup driver with options */
1660a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	if (au1200fb_setup(pd))
1661a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		return -ENODEV;
1662a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1663a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	/* Point to the panel selected */
1664a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	panel = &known_lcd_panels[panel_index];
1665a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	win = &windows[window_index];
1666a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1667a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
1668a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
1669a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1670c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	/* shut gcc up */
1671c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	ret = 0;
1672c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	fbdev = NULL;
1673f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
16748be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss	for (plane = 0; plane < device_count; ++plane) {
1675f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		bpp = winbpp(win->w[plane].mode_winctrl1);
1676f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (win->w[plane].xres == 0)
1677f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			win->w[plane].xres = panel->Xres;
1678f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (win->w[plane].yres == 0)
1679f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			win->w[plane].yres = panel->Yres;
1680f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1681c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
1682c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss					&dev->dev);
1683c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		if (!fbi)
1684c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss			goto failed;
1685c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss
1686c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		_au1200fb_infos[plane] = fbi;
1687c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		fbdev = fbi->par;
1688c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		fbdev->fb_info = fbi;
1689a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss		fbdev->pd = pd;
1690c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss
1691f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		fbdev->plane = plane;
1692f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1693f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Allocate the framebuffer to the maximum screen size */
1694f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
1695f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
169693019734555f8df32239c5922fe2b770c0a08eaaManuel Lauss		fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev,
1697f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				PAGE_ALIGN(fbdev->fb_len),
1698f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				&fbdev->fb_phys, GFP_KERNEL);
1699f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (!fbdev->fb_mem) {
1700f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_err("fail to allocate frambuffer (size: %dK))",
1701f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				  fbdev->fb_len / 1024);
1702f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			return -ENOMEM;
1703f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1704f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1705f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/*
1706f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		 * Set page reserved so that mmap will work. This is necessary
1707f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		 * since we'll be remapping normal memory.
1708f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		 */
1709f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		for (page = (unsigned long)fbdev->fb_phys;
1710f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		     page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
1711f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			     fbdev->fb_len);
1712f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		     page += PAGE_SIZE) {
1713f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
1714f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1715f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
1716f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
1717f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1718f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Init FB data */
1719f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
1720f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			goto failed;
1721f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1722f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Register new framebuffer */
1723c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		ret = register_framebuffer(fbi);
1724c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		if (ret < 0) {
1725f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			print_err("cannot register new framebuffer");
1726f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			goto failed;
1727f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		}
1728f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1729c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		au1200fb_fb_set_par(fbi);
1730f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1731f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
1732f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		if (plane == 0)
1733c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss			if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
1734f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle				/* Start display and show logo on boot */
1735c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss				fb_set_cmap(&fbi->cmap, fbi);
1736c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss				fb_show_logo(fbi, FB_ROTATE_UR);
1737f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle			}
1738f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif
1739f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1740f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1741f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Now hook interrupt too */
17421630d85a831273868651d46d74f069e0cdf9b698Manuel Lauss	irq = platform_get_irq(dev, 0);
17431630d85a831273868651d46d74f069e0cdf9b698Manuel Lauss	ret = request_irq(irq, au1200fb_handle_irq,
1744f8798ccbefc0e4ef7438c080b7ba0410738c8cfaYong Zhang			  IRQF_SHARED, "lcd", (void *)dev);
17451630d85a831273868651d46d74f069e0cdf9b698Manuel Lauss	if (ret) {
1746f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		print_err("fail to request interrupt line %d (err: %d)",
17471630d85a831273868651d46d74f069e0cdf9b698Manuel Lauss			  irq, ret);
1748f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		goto failed;
1749f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1750f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1751a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	platform_set_drvdata(dev, pd);
1752a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1753a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	/* Kickstart the panel */
1754a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	au1200_setpanel(panel, pd);
1755a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss
1756f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1757f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1758f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechlefailed:
1759f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* NOTE: This only does the current plane/window that failed; others are still active */
1760c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	if (fbi) {
1761c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		if (fbi->cmap.len != 0)
1762c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss			fb_dealloc_cmap(&fbi->cmap);
1763c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		kfree(fbi->pseudo_palette);
1764c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	}
1765f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	if (plane == 0)
1766f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		free_irq(AU1200_LCD_INT, (void*)dev);
1767f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return ret;
1768f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1769f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
177048c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartmanstatic int au1200fb_drv_remove(struct platform_device *dev)
1771f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1772a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_platdata *pd = platform_get_drvdata(dev);
1773f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	struct au1200fb_device *fbdev;
1774c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss	struct fb_info *fbi;
1775f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	int plane;
1776f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1777f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	/* Turn off the panel */
1778a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	au1200_setpanel(NULL, pd);
1779f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
17808be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss	for (plane = 0; plane < device_count; ++plane)	{
1781c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		fbi = _au1200fb_infos[plane];
1782c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		fbdev = fbi->par;
1783f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1784f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle		/* Clean up all probe data */
1785c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		unregister_framebuffer(fbi);
1786c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		if (fbi->cmap.len != 0)
1787c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss			fb_dealloc_cmap(&fbi->cmap);
1788c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		kfree(fbi->pseudo_palette);
1789c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss
1790c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		framebuffer_release(fbi);
1791c329f606a23e13fe952768cb9c32ea929ed91480Manuel Lauss		_au1200fb_infos[plane] = NULL;
1792f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	}
1793f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
17941630d85a831273868651d46d74f069e0cdf9b698Manuel Lauss	free_irq(platform_get_irq(dev, 0), (void *)dev);
1795f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1796f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1797f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1798f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1799f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#ifdef CONFIG_PM
180098707fcc044c2e6120448041bf738d1b134cfaa4Manuel Laussstatic int au1200fb_drv_suspend(struct device *dev)
1801f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1802a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_platdata *pd = dev_get_drvdata(dev);
1803a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	au1200_setpanel(NULL, pd);
180498707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
180598707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	lcd->outmask = 0;
18062f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss	wmb(); /* drain writebuffer */
180798707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
1808f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1809f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
1810f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
181198707fcc044c2e6120448041bf738d1b134cfaa4Manuel Laussstatic int au1200fb_drv_resume(struct device *dev)
1812f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle{
1813a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	struct au1200fb_platdata *pd = dev_get_drvdata(dev);
181498707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	struct fb_info *fbi;
181598707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	int i;
181698707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
181798707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	/* Kickstart the panel */
1818a9b71a8f0f42efe1a21154667ca02305c950d30aManuel Lauss	au1200_setpanel(panel, pd);
181998707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
18208be90b07ac2a07b4f1eb685caa97e88b9f85ef27Manuel Lauss	for (i = 0; i < device_count; i++) {
182198707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss		fbi = _au1200fb_infos[i];
182298707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss		au1200fb_fb_set_par(fbi);
182398707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	}
182498707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
1825f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	return 0;
1826f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle}
182798707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
182898707fcc044c2e6120448041bf738d1b134cfaa4Manuel Laussstatic const struct dev_pm_ops au1200fb_pmops = {
182998707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	.suspend	= au1200fb_drv_suspend,
183098707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	.resume		= au1200fb_drv_resume,
183198707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	.freeze		= au1200fb_drv_suspend,
183298707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss	.thaw		= au1200fb_drv_resume,
183398707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss};
183498707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
183598707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss#define AU1200FB_PMOPS	(&au1200fb_pmops)
183698707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss
183798707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss#else
183898707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss#define AU1200FB_PMOPS	NULL
1839f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle#endif /* CONFIG_PM */
1840f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
18417a192ec334cab9fafe3a8665a65af398b0e24730Ming Leistatic struct platform_driver au1200fb_driver = {
18427a192ec334cab9fafe3a8665a65af398b0e24730Ming Lei	.driver = {
184398707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss		.name	= "au1200-lcd",
184498707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss		.owner	= THIS_MODULE,
184598707fcc044c2e6120448041bf738d1b134cfaa4Manuel Lauss		.pm	= AU1200FB_PMOPS,
18467a192ec334cab9fafe3a8665a65af398b0e24730Ming Lei	},
1847f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle	.probe		= au1200fb_drv_probe,
184848c68c4f1b542444f175a9e136febcecf3e704d8Greg Kroah-Hartman	.remove		= au1200fb_drv_remove,
1849f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle};
1850d07b319143bd247410fbb5e1859a4928af7a42ceHanjun Guomodule_platform_driver(au1200fb_driver);
1851f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf Baechle
1852f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf BaechleMODULE_DESCRIPTION(DRIVER_DESC);
1853f95ec3c6df271ae4e6290cd6b95c18a009c76dc9Ralf BaechleMODULE_LICENSE("GPL");
1854