1 /*  IT8181 console frame buffer driver---it8181fb.c
2  *
3  *  Copyright (C) 2001 Integrated Technology Express, Inc.
4  *  Copyright (C) 2001 MontaVista Software Inc.
5  *  Copyright (C) 2002,2003 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
6  *
7  *  Initial work by rich.liu@ite.com.tw
8  *
9  *  Rewritten by MontaVista Software, Inc.
10  *         	stevel@mvista.com or source@mvista.com
11  *
12  *  This program is free software; you can redistribute  it and/or modify it
13  *  under  the terms of  the GNU General  Public License as published by the
14  *  Free Software Foundation;  either version 2 of the  License, or (at your
15  *  option) any later version.
16  *
17  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
18  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
19  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
20  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
21  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
23  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
25  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  *  You should have received a copy of the  GNU General Public License along
29  *  with this program; if not, write  to the Free Software Foundation, Inc.,
30  *  675 Mass Ave, Cambridge, MA 02139, USA.
31  */
32 /*
33  * Changes:
34  * Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
35  *	- Added support of NEC VR4111 and VR4121.
36  *	- rewrote it8181fb_set_par()
37  */
38 #include <linux/config.h>
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/errno.h>
42 #include <linux/string.h>
43 #include <linux/mm.h>
44 #include <linux/tty.h>
45 #include <linux/slab.h>
46 #include <linux/vmalloc.h>
47 #include <linux/delay.h>
48 #include <linux/interrupt.h>
49 #include <asm/uaccess.h>
50 #include <linux/fb.h>
51 #include <linux/init.h>
52 #include <linux/pci.h>
53 #include <asm/io.h>
54 
55 #include <video/fbcon.h>
56 #include <video/fbcon-mfb.h>
57 #include <video/fbcon-cfb2.h>
58 #include <video/fbcon-cfb4.h>
59 #include <video/fbcon-cfb8.h>
60 #include <video/fbcon-cfb16.h>
61 #include <video/fbcon-cfb24.h>
62 #include <video/fbcon-cfb32.h>
63 #include "vga.h"
64 
65 static const struct {
66 	int f_pix_l; // kHz
67 	int f_pix_h; // kHz
68 	int m, n, p;
69 } std_pll_freq[] = {
70 	{24923, 25427, 1, 14, 3}, // 25.175 MHz +- 1%
71 	{31185, 31815, 3, 53, 3}, // 31.5 MHz +- 1%
72 	{39600, 40400, 5, 56, 2}, // 40 MHz +- 1%
73 	{49005, 49995, 6, 83, 2}, // 49.5 MHz +- 1%
74 	{49500, 50500, 1, 14, 2}, // 50 MHz +- 1%
75 	{64350, 65650, 9, 82, 1}, // 65 MHz +- 1%
76 	{74250, 75750, 2, 21, 1}, // 75 MHz +- 1%
77 	{0, 0, 0, 0, 0}
78 };
79 
80 // FIXME: this is just a guess
81 #define PLL_MAX_M		18
82 
83 #define IT8181_GUI_SIZE		0x8000L		/* 32kB */
84 #define IT8181_MMIO_SIZE	0x10000L	/* 64kB */
85 #define IT8181_FB_SIZE		0x400000L	/* 4MB  */
86 #define IT8181_CFG_SIZE		0x50UL
87 
88 #define PICOS2KHZ(a)		(1000000000UL/(a))
89 #define KHZ2PICOS(a)		(1000000000UL/(a))
90 
91 #define CLOCK_REF		14318 // KHz
92 
93 #define IT8181_STANDBY		0x44	/* Standby register */
94 #define IT8181_PLL1		0x48	/* PLL1 register */
95 #define IT8181_PLL2		0x4c	/* PLL2 register */
96 
97 #define IT8181_PLL1_RST		0x00004000	/* PLL1 reset */
98 #define IT8181_PLL2_RST		0x00008000
99 
100 #define IT8181_MODULE_NAME	"IT8181"
101 #define PFX IT8181_MODULE_NAME
102 
103 #undef IT8181_DEBUG
104 
105 #ifdef IT8181_DEBUG
106 #define dbg(format, arg...) \
107     printk(__FUNCTION__ ": " format "\n" , ## arg)
108   //printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg)
109 #else
110 #define dbg(format, arg...) do {} while (0)
111 #endif
112 #define err(format, arg...) printk(KERN_ERR PFX ": " format "\n" , ## arg)
113 #define info(format, arg...) printk(KERN_INFO PFX ": " format "\n" , ## arg)
114 #define warn(format, arg...) printk(KERN_WARNING PFX ": " format "\n" , ## arg)
115 #define emerg(format, arg...) printk(KERN_EMERG PFX ": " format "\n" , ## arg)
116 
117 #define CMAPSIZE		16
118 #define arraysize(x)		(sizeof(x)/sizeof(*(x)))
119 
120 /*
121  * These are fb_var_screeninfo's for 640x480, 800x600, and
122  * 1024x768. The bpp field is filled in later.
123  */
124 static const struct fb_var_screeninfo it8181_var_table[] = {
125 	{	// 640x480@75, 31.5MHz dotclock
126 		640, 480, 640, 480, 0, 0, -1, 0,
127 		{0}, {0}, {0}, {0},
128 		0, FB_ACTIVATE_NOW, -1, -1, 0,
129 		31747, 120, 16, 16, 1, 64, 3,
130 		0, FB_VMODE_NONINTERLACED },
131 	{	// 800x600@72, 50.00MHz dotclock
132 		800, 600, 800, 600, 0, 0, -1, 0,
133 		{0}, {0}, {0}, {0},
134 		0, FB_ACTIVATE_NOW, -1, -1, 0,
135 		20000, 64, 56, 23, 37, 120, 6,
136 		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
137 		FB_VMODE_NONINTERLACED },
138 	{	// 1024x768@70, 75.00MHz dotclock
139 		1024, 768, 1024, 768, 0, 0, -1, 0,
140 		{0}, {0}, {0}, {0},
141 		0, FB_ACTIVATE_NOW, -1, -1, 0,
142 		13334, 144, 24, 29, 3, 136, 6,
143 		0, FB_VMODE_NONINTERLACED }
144 };
145 
146 enum {
147 	RES_640x480 = 0,
148 	RES_800x600,
149 	RES_1024x768
150 };
151 
152 /*
153  * The default resolution and color depth to use if
154  * none was specified on command line.
155  */
156 #define DEFAULT_RES		RES_800x600
157 #define DEFAULT_BPP		16
158 #define DEFAULT_MEMORY_BASE	0
159 #define DEFAULT_CONFIG_OFFSET	0
160 
161 static const char default_mode[] = "800x600-70";
162 static char __initdata fontname[40] = { 0 };
163 static const char *mode_option __initdata = NULL;
164 static int default_bpp __initdata = DEFAULT_BPP;
165 static int default_res __initdata = DEFAULT_RES;
166 static int default_memory_base __initdata = DEFAULT_MEMORY_BASE;
167 static int default_config_offset __initdata = DEFAULT_CONFIG_OFFSET;
168 
169 struct it8181fb_par {
170         struct fb_var_screeninfo var;
171 
172         int HorizRes;          /* The x resolution in pixel */
173         int HorizTotal;
174         int HorizDispEnd;
175         int HorizBlankStart;
176         int HorizBlankEnd;
177         int HorizSyncStart;
178         int HorizSyncEnd;
179 
180         int VertRes;           /* the physical y resolution in scanlines */
181         int VertTotal;
182         int VertDispEnd;
183         int VertSyncStart;
184         int VertSyncEnd;
185         int VertBlankStart;
186         int VertBlankEnd;
187 
188 	int pll1_N, pll1_M, pll1_P; // PLL1 settings for pixel clock
189 	int pll2_N, pll2_M, pll2_P; // PLL2 settings for memory clock
190 	int pclk;                // pixel clock from above PLL settings, KHz
191 
192 	int line_length;  // in bytes
193 	int cmap_len;     // color-map length
194 };
195 
196 struct it8181fb_info {
197         struct fb_info_gen gen;
198 	struct it8181fb_par current_par;
199 	struct pci_dev *pdev;
200         struct display disp;
201         unsigned int itConfigAddrVirt;
202         unsigned int itMmioAddrVirt;
203         unsigned int itFbAddrVirt;
204         unsigned int itGuiCtrlVirt;
205         unsigned int itMmioAddrPhys;
206         unsigned int itFbAddrPhys;
207         unsigned int itGuiCtrlPhys;
208 	int blank_mode;
209 
210         struct it8181fb_info *next;
211 };
212 
213 static struct it8181fb_info *fb_it8181;
214 static u32 itMmioAddr;
215 static int it8181fb_lcd;
216 static int it8181fb_memory_type;
217 
218 static char it8181fb_name[16] = IT8181_MODULE_NAME;
219 
220 static union {
221 #ifdef FBCON_HAS_CFB16
222 	u16 cfb16[CMAPSIZE];
223 #endif
224 #ifdef FBCON_HAS_CFB24
225 	u32 cfb24[CMAPSIZE];
226 #endif
227 #ifdef FBCON_HAS_CFB32
228 	u32 cfb32[CMAPSIZE];
229 #endif
230 } fbcon_cmap;
231 
232 /* Interface used by the world */
233 int it8181fb_init(void);
234 int it8181fb_setup(char *options, int *ints);
235 static int it8181fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
236 			  u_long arg, int con, struct fb_info *info);
237 
238 /* Hardware Specific Routines */
239 static void it8181fb_detect (void);
240 static int it8181fb_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
241 				struct fb_info_gen *info);
242 static int it8181fb_decode_var (const struct fb_var_screeninfo *var, void *par,
243 				struct fb_info_gen *info);
244 static int it8181fb_encode_var (struct fb_var_screeninfo *var, const void *par,
245 				struct fb_info_gen *info);
246 static void it8181fb_get_par (void *par, struct fb_info_gen *info);
247 static void it8181fb_set_par (const void *par, struct fb_info_gen *info);
248 static int it8181fb_getcolreg (unsigned regno, unsigned *red, unsigned *green,
249 			       unsigned *blue, unsigned *transp,
250 			       struct fb_info *info);
251 static int it8181fb_setcolreg (unsigned regno, unsigned red, unsigned green,
252                             unsigned blue, unsigned transp,
253 			       struct fb_info *info);
254 static int it8181fb_pan_display (const struct fb_var_screeninfo *var,
255 				 struct fb_info_gen *info);
256 static int it8181fb_blank (int blank_mode, struct fb_info_gen *info);
257 static void it8181fb_set_disp (const void *par, struct display *disp,
258 			       struct fb_info_gen *info);
259 
260 /* Internal routines */
261 static void set_color_bitfields(struct fb_var_screeninfo *var);
262 static int it8181fb_calc_pixclock(struct it8181fb_par* par);
263 static void it8181SetPLL(const struct it8181fb_par* par,
264 			 const struct it8181fb_info* info);
265 
266 /* function table of the above functions */
267 static struct fb_ops it8181fb_ops = {
268         owner:          THIS_MODULE,
269         fb_get_fix:     fbgen_get_fix,
270         fb_get_var:     fbgen_get_var,
271         fb_set_var:     fbgen_set_var,
272         fb_get_cmap:    fbgen_get_cmap,
273         fb_set_cmap:    fbgen_set_cmap,
274         fb_pan_display: fbgen_pan_display,
275         fb_ioctl:       it8181fb_ioctl,
276 };
277 
278 /* function table of the above functions */
279 static struct fbgen_hwswitch it8181fb_hwswitch =
280 {
281         it8181fb_detect,
282         it8181fb_encode_fix,
283         it8181fb_decode_var,
284         it8181fb_encode_var,
285         it8181fb_get_par,
286         it8181fb_set_par,
287         it8181fb_getcolreg,
288         it8181fb_setcolreg,
289         it8181fb_pan_display,
290         it8181fb_blank,
291         it8181fb_set_disp
292 };
293 
itReadConfigDword(const struct it8181fb_info * info,int where,u32 * val)294 static int itReadConfigDword(const struct it8181fb_info *info, int where, u32 *val)
295 {
296 	int result = 0;
297 
298 #ifdef CONFIG_PCI
299 	if (info->pdev)
300 		result =  pci_read_config_dword(info->pdev, where, val);
301 	else
302 #endif
303 		*val = readl(info->itConfigAddrVirt + where);
304 
305 	return result;
306 }
307 
itWriteConfigDword(const struct it8181fb_info * info,int where,u32 val)308 static int itWriteConfigDword(const struct it8181fb_info *info, int where, u32 val)
309 {
310 	int result = 0;
311 
312 #ifdef CONFIG_PCI
313 	if (info->pdev)
314 		result =  pci_write_config_dword(info->pdev, where, val);
315 	else
316 #endif
317 		writel(val, info->itConfigAddrVirt+ where);
318 
319 	return result;
320 }
321 
itReadRegExtB(unsigned char addr)322 static inline int itReadRegExtB(unsigned char addr)
323 {
324 	writeb(addr,itMmioAddr+0x3ce);
325 	return readb(itMmioAddr+0x3cf);
326 }
327 
itWriteRegExtB(unsigned char addr,unsigned char value)328 static inline void itWriteRegExtB(unsigned char addr, unsigned char value)
329 {
330 	int tmp;
331 	writeb(addr,itMmioAddr+0x3ce);
332 	writeb(value,itMmioAddr+0x3cf);
333 	tmp = itReadRegExtB(addr);
334 }
335 
itExtBLock(void)336 static inline void itExtBLock(void)
337 {
338 	itWriteRegExtB(0x0b,0x35);
339 	if (itReadRegExtB(0x0b) & 1)
340 		dbg("ExtB still unlocked!");
341 }
342 
itExtBUnlock(void)343 static inline void itExtBUnlock(void)
344 {
345 	itWriteRegExtB(0x0b,0xca);
346 	if (!(itReadRegExtB(0x0b) & 1))
347 		dbg("ExtB still locked!");
348 }
349 
itReadRegExtA(unsigned char addr)350 static inline int itReadRegExtA(unsigned char addr)
351 {
352 	writeb(addr,itMmioAddr+0x3d6);
353 	return readb(itMmioAddr+0x3d7);
354 }
355 
itWriteRegExtA(unsigned char addr,unsigned char value)356 static inline void itWriteRegExtA(unsigned char addr,unsigned char value)
357 {
358 	int tmp;
359 	writeb(addr,itMmioAddr+0x3d6);
360 	writeb(value,itMmioAddr+0x3d7);
361 	tmp = itReadRegExtA(addr);
362 }
363 
itExtALock(void)364 static inline void itExtALock(void)
365 {
366 	itWriteRegExtA(0x0b,0xce);
367 }
368 
itExtAUnlock(void)369 static inline void itExtAUnlock(void)
370 {
371 	itWriteRegExtA(0x0b,0xec);
372 }
373 
itReadRegCrtc(unsigned char addr)374 static inline int itReadRegCrtc(unsigned char addr)
375 {
376 	writeb(addr,itMmioAddr+VGA_CRT_IC);
377 	return readb(itMmioAddr+VGA_CRT_DC);
378 }
379 
itWriteRegCrtc(unsigned char addr,unsigned char value)380 static inline void itWriteRegCrtc(unsigned char addr,unsigned char value)
381 {
382 	int tmp;
383 	writeb(addr,itMmioAddr+VGA_CRT_IC);
384 	writeb(value,itMmioAddr+VGA_CRT_DC);
385 	tmp = itReadRegCrtc(addr);
386 }
387 
itReadRegMisc(void)388 static inline uint8_t itReadRegMisc(void)
389 {
390 	return readb(itMmioAddr+VGA_MIS_R);
391 }
392 
itWriteRegMisc(unsigned char value)393 static inline void itWriteRegMisc(unsigned char value)
394 {
395 	writeb(value, itMmioAddr+VGA_MIS_W);
396 }
397 
itReadRegSEQ(unsigned char addr)398 static inline int itReadRegSEQ(unsigned char addr)
399 {
400 	writeb(addr, itMmioAddr+VGA_SEQ_I);
401 	return readb(itMmioAddr+VGA_SEQ_D);
402 }
403 
itWriteRegSEQ(unsigned char addr,unsigned char value)404 static inline void itWriteRegSEQ(unsigned char addr,unsigned char value)
405 {
406 	writeb(addr, itMmioAddr+VGA_SEQ_I);
407 	writeb(value, itMmioAddr+VGA_SEQ_D);
408 }
409 
set_color_bitfields(struct fb_var_screeninfo * var)410 static void set_color_bitfields(struct fb_var_screeninfo *var)
411 {
412 	switch (var->bits_per_pixel) {
413 	case 1:
414 	case 8:
415 		var->red.offset = 0;
416 		var->red.length = 8;
417 		var->green.offset = 0;
418 		var->green.length = 8;
419 		var->blue.offset = 0;
420 		var->blue.length = 8;
421 		var->transp.offset = 0;
422 		var->transp.length = 0;
423 		break;
424 	case 16:	/* RGB 565 */
425 		var->red.offset = 11;
426 		var->red.length = 5;
427 		var->green.offset = 5;
428 		var->green.length = 6;
429 		var->blue.offset = 0;
430 		var->blue.length = 5;
431 		var->transp.offset = 0;
432 		var->transp.length = 0;
433 		break;
434 	case 24:	/* RGB 888 */
435 		var->red.offset = 16;
436 		var->red.length = 8;
437 		var->green.offset = 8;
438 		var->green.length = 8;
439 		var->blue.offset = 0;
440 		var->blue.length = 8;
441 		var->transp.offset = 0;
442 		var->transp.length = 0;
443 		break;
444 	case 32:	/* RGBA 8888 */
445 		var->red.offset = 0;
446 		var->red.length = 8;
447 		var->green.offset = 8;
448 		var->green.length = 8;
449 		var->blue.offset = 16;
450 		var->blue.length = 8;
451 		var->transp.offset = 24;
452 		var->transp.length = 8;
453 		break;
454 	}
455 
456 	var->red.msb_right = 0;
457 	var->green.msb_right = 0;
458 	var->blue.msb_right = 0;
459 	var->transp.msb_right = 0;
460 }
461 
462 
it8181fb_detect(void)463 static void it8181fb_detect (void)
464 {
465 	dbg("");
466 }
467 
it8181fb_encode_fix(struct fb_fix_screeninfo * fix,const void * _par,struct fb_info_gen * _info)468 static int it8181fb_encode_fix(struct fb_fix_screeninfo *fix,
469 				const void* _par,
470 				struct fb_info_gen* _info)
471 {
472         struct it8181fb_par *par = (struct it8181fb_par *) _par;
473         struct it8181fb_info *info = (struct it8181fb_info *) _info;
474 	struct fb_var_screeninfo* var = &par->var;
475 
476 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
477 	strcpy(fix->id, it8181fb_name);
478 
479 	fix->smem_start = info->itFbAddrPhys;
480 	fix->smem_len = IT8181_FB_SIZE;
481 	fix->mmio_start = info->itMmioAddrPhys;
482 	fix->mmio_len = IT8181_MMIO_SIZE;
483 	fix->type = FB_TYPE_PACKED_PIXELS;
484 	fix->type_aux = 0;
485         fix->visual = (var->bits_per_pixel <= 8) ?
486 		FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
487 	fix->ywrapstep = 0;
488 	fix->xpanstep = 1;
489 	fix->ypanstep = 1;
490 	fix->line_length = par->line_length;
491 
492 	return 0;
493 }
494 
it8181fb_decode_var(const struct fb_var_screeninfo * var,void * _par,struct fb_info_gen * _info)495 static int  it8181fb_decode_var(const struct fb_var_screeninfo *var,
496 				void *_par,
497 				struct fb_info_gen *_info)
498 {
499         struct it8181fb_par *par = (struct it8181fb_par *) _par;
500 	int xres, rm, hsync, lm;
501 	int yres, bm, vsync, um;
502 
503 	if (var->vmode & FB_VMODE_DOUBLE) {
504 		dbg("double-scan modes not supported");
505 		return -EINVAL;
506 	}
507 	if (var->vmode & FB_VMODE_INTERLACED) {
508 		dbg("interlaced modes not supported");
509 		return -EINVAL;
510 	}
511 
512 	if (!((var->xres == 640 && var->yres == 480) ||
513 	      (var->xres == 800 && var->yres == 600) ||
514 	      (var->xres == 1024 && var->yres == 768))) {
515 		dbg("resolution not supported: %dx%d",
516 		    var->xres, var->yres);
517 		return -EINVAL;
518 	}
519 
520         memset (par, 0, sizeof (struct it8181fb_par));
521         par->var = *var;
522 
523 	switch (var->bits_per_pixel) {
524 	case 2 ... 8:
525 		par->var.bits_per_pixel = 8;
526 		break;
527 	case 9 ... 16:
528 		par->var.bits_per_pixel = 16;
529 		break;
530 	case 17 ... 24:
531 		par->var.bits_per_pixel = 24;
532 		break;
533 	case 25 ... 32:
534 		par->var.bits_per_pixel = 32;
535 		break;
536 	default:
537 		dbg("color depth %d bpp not supported", var->bits_per_pixel);
538 		return -EINVAL;
539 	}
540 
541 	par->var.width = par->var.height = -1;
542 	/* no virtual display for now (no panning/scrolling) */
543 	par->var.xoffset = par->var.yoffset = 0;
544 	par->var.xres_virtual = par->var.xres;
545 	par->var.yres_virtual = par->var.yres;
546 	/* no accels */
547 	par->var.accel_flags = 0;
548 
549 	set_color_bitfields(&par->var);
550 	par->cmap_len = (par->var.bits_per_pixel == 8) ? 256 : 16;
551 
552 	/*
553 	 *  check memory limit
554 	 */
555 	par->line_length =
556 		par->var.xres_virtual * (par->var.bits_per_pixel>>3);
557 	if (par->line_length * par->var.yres_virtual > IT8181_FB_SIZE) {
558 		dbg("not enough video memory for virtual res %dx%dx%d!",
559 		    par->var.xres_virtual, par->var.yres_virtual,
560 		    par->var.bits_per_pixel);
561 		return -ENOMEM;
562 	}
563 
564 	if (it8181fb_calc_pixclock(par)) {
565 		return -EINVAL;
566 	}
567 
568 	xres = var->xres;
569 	rm = var->right_margin;
570 	hsync = var->hsync_len;
571 	lm = var->left_margin;
572 
573 	yres = var->yres;
574 	bm = var->lower_margin;
575 	vsync = var->vsync_len;
576 	um = var->upper_margin;
577 
578 	par->HorizRes = xres;
579 	par->HorizTotal = (xres + rm + hsync + lm) / 8 - 5;
580 	par->HorizDispEnd = xres / 8 - 1;
581 	par->HorizBlankStart = xres / 8;
582 	par->HorizBlankEnd = par->HorizTotal + 5; // does not count with "-5"
583 	par->HorizSyncStart = (xres + rm) / 8 + 1;
584 	par->HorizSyncEnd = (xres + rm + hsync) / 8 + 1;
585 
586 	par->VertRes = yres;
587 	par->VertTotal = yres + bm + vsync + um - 2;
588 	par->VertDispEnd = yres - 1;
589 	par->VertBlankStart = yres;
590 	par->VertBlankEnd = par->VertTotal;
591 	par->VertSyncStart = yres + bm - 1;
592 	par->VertSyncEnd = yres + bm + vsync - 1;
593 
594 	return 0;
595 }
596 
it8181fb_encode_var(struct fb_var_screeninfo * var,const void * par,struct fb_info_gen * info)597 static int  it8181fb_encode_var(struct fb_var_screeninfo *var,
598 				const void *par,
599 				struct fb_info_gen *info)
600 {
601 	*var = ((struct it8181fb_par *)par)->var;
602 	return 0;
603 }
604 
it8181fb_set_disp(const void * _par,struct display * disp,struct fb_info_gen * _info)605 static void it8181fb_set_disp(const void *_par, struct display *disp,
606 			      struct fb_info_gen *_info)
607 {
608         struct it8181fb_par *par = (struct it8181fb_par *) _par;
609         struct it8181fb_info *info = (struct it8181fb_info *) _info;
610 
611 	disp->screen_base = (char *)info->itFbAddrVirt;
612 
613 	switch (par->var.bits_per_pixel) {
614 #ifdef FBCON_HAS_MFB
615 	case 1:
616 		disp->dispsw = &fbcon_mfb;
617 		break;
618 #endif
619 #ifdef FBCON_HAS_CFB2
620 	case 2:
621 		disp->dispsw = &fbcon_cfb2;
622 		break;
623 #endif
624 #ifdef FBCON_HAS_CFB4
625 	case 4:
626 		disp->dispsw = &fbcon_cfb4;
627 		break;
628 #endif
629 #ifdef FBCON_HAS_CFB8
630 	case 8:
631 		disp->dispsw = &fbcon_cfb8;
632 		break;
633 #endif
634 #ifdef FBCON_HAS_CFB16
635 	case 16:
636 		disp->dispsw = &fbcon_cfb16;
637 		disp->dispsw_data = fbcon_cmap.cfb16;
638 		break;
639 #endif
640 #ifdef FBCON_HAS_CFB24
641 	case 24:
642 		disp->dispsw = &fbcon_cfb24;
643 		disp->dispsw_data = fbcon_cmap.cfb24;
644 		break;
645 #endif
646 #ifdef FBCON_HAS_CFB32
647 	case 32:
648 		disp->dispsw = &fbcon_cfb32;
649 		disp->dispsw_data = fbcon_cmap.cfb32;
650 		break;
651 #endif
652 	default:
653 		disp->dispsw = &fbcon_dummy;
654 		disp->dispsw_data = NULL;
655 		break;
656 	}
657 }
658 
it8181fb_ioctl(struct inode * inode,struct file * file,u_int cmd,u_long arg,int con,struct fb_info * info)659 static int it8181fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
660 			  u_long arg, int con, struct fb_info *info)
661 {
662 	/* nothing to do yet */
663 	return -EINVAL;
664 }
665 
it8181fb_panel_poweron(void)666 static inline void it8181fb_panel_poweron(void)
667 {
668 	if (it8181fb_lcd != 0) {
669 		itExtAUnlock();
670 		itWriteRegExtA(0x9b, 0x01);
671 		itExtALock();
672 
673 		mdelay(120);
674 	}
675 }
676 
it8181fb_panel_poweroff(void)677 static inline void it8181fb_panel_poweroff(void)
678 {
679 	if (it8181fb_lcd != 0) {
680 		itExtAUnlock();
681 		itWriteRegExtA(0x9b, 0x00);
682 		itExtALock();
683 
684 		mdelay(120);
685 	}
686 }
687 
688 /*
689  *  Blank the display.
690  *
691  * 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off
692  */
it8181fb_blank(int mode,struct fb_info_gen * _info)693 static int it8181fb_blank(int mode, struct fb_info_gen *_info)
694 {
695 	struct it8181fb_info *p = (struct it8181fb_info *)_info;
696 
697         if (p->blank_mode == mode)
698                 return 0;
699 
700 	itExtBUnlock();
701 
702 	mdelay(25);
703 
704 	switch (mode) {
705 	case 0:
706 		// turn display sync's back on
707 		itWriteRegExtB(0x3c, 0x00);
708 		itWriteRegSEQ(VGA_SEQ_CLOCK_MODE, 0); // unblank
709 
710 		it8181fb_panel_poweron();
711 		break;
712 	case 1:
713 		// turn display sync's back on
714 		itWriteRegExtB(0x3c, 0x00);
715                 itWriteRegSEQ(VGA_SEQ_CLOCK_MODE, 0x20); // blank
716 
717 		it8181fb_panel_poweroff();
718 		break;
719 	case 2:
720                 itWriteRegSEQ(VGA_SEQ_CLOCK_MODE, 0x20); // blank
721 		itWriteRegExtB(0x3c, 0x08); // disable vsync
722 
723 		it8181fb_panel_poweroff();
724 		break;
725 	case 3:
726                 itWriteRegSEQ(VGA_SEQ_CLOCK_MODE, 0x20); // blank
727 		itWriteRegExtB(0x3c, 0x02); // disable hsync
728 
729 		it8181fb_panel_poweroff();
730 		break;
731 	case 4:
732                 itWriteRegSEQ(VGA_SEQ_CLOCK_MODE, 0x20); // blank
733 		itWriteRegExtB(0x3c, 0x0a); // disable sync
734 
735 		it8181fb_panel_poweroff();
736 		break;
737 	}
738 
739 	itExtBLock();
740 
741 	p->blank_mode = mode;
742 
743 	return 0;
744 }
745 
it8181fb_calc_pixclock(struct it8181fb_par * par)746 static int it8181fb_calc_pixclock(struct it8181fb_par* par)
747 {
748 	int i;
749 	int f_pix, f_actual;
750 
751 	/*
752 	 * If the desired pixel clock is one of the standard
753 	 * VESA frequencies, pull the {N,M,P} values from the
754 	 * std_pll_freq[] table, otherwise we have to calculate
755 	 * the {N,M,P} values.
756 	 */
757 
758 	f_pix = PICOS2KHZ(par->var.pixclock);
759 
760 	for (i=0; std_pll_freq[i].f_pix_l; i++) {
761 		if (f_pix >= std_pll_freq[i].f_pix_l &&
762 		    f_pix <= std_pll_freq[i].f_pix_h) {
763 			par->pll1_N = std_pll_freq[i].n;
764 			par->pll1_M = std_pll_freq[i].m;
765 			par->pll1_P = std_pll_freq[i].p;
766 			break;
767 		}
768 	}
769 
770 	if (!std_pll_freq[i].f_pix_l) {
771 		int r, N, M, P;
772 		// Pixel clock is not one of the standard VESA frequencies.
773 		if (f_pix < 2*CLOCK_REF)      P = 3;
774 		else if (f_pix < 4*CLOCK_REF) P = 2;
775 		else if (f_pix < 6*CLOCK_REF) P = 1;
776 		else                          P = 0;
777 
778 		r = ((1<<10) * f_pix * (1<<P)) / CLOCK_REF;
779 
780 		if (r > 255*(1<<10) || r < (1<<10)/PLL_MAX_M) {
781 			dbg("desired pixclock out of range");
782 			return -EINVAL;
783 		}
784 
785 		if (r == (1<<10)) {
786 			// r = 1.0
787 			N = M = PLL_MAX_M;
788 		} else if (r > (1<<10)) {
789 			// r > 1.0
790 			for (N=255; N>1; N--) {
791 				// round-up
792 				M = ((N*(1<<11) + (1<<10)) / r) / 2;
793 				if (M <= PLL_MAX_M)
794 					break;
795 			}
796 		} else {
797 			// r < 1.0
798 			M = PLL_MAX_M;
799 			N = (PLL_MAX_M * r + (1<<9)) / (1<<10); // round-up
800 		}
801 
802 		par->pll1_N = N;
803 		par->pll1_M = M;
804 		par->pll1_P = P;
805 	}
806 
807 
808 	f_actual = (par->pll1_N * CLOCK_REF) / (par->pll1_M * (1<<par->pll1_P));
809 
810 	dbg("N=%d, M=%d, P=%d", par->pll1_N, par->pll1_M, par->pll1_P);
811 	dbg("desired=%d KHz, actual=%d KHz, error=%d%%",
812 	    f_pix, f_actual, (100*abs(f_actual - f_pix)) / f_pix);
813 
814 	par->var.pixclock = KHZ2PICOS(f_actual);
815 	return 0;
816 }
817 
it8181SetPLL(const struct it8181fb_par * par,const struct it8181fb_info * info)818 static void it8181SetPLL(const struct it8181fb_par* par,
819 			 const struct it8181fb_info* info)
820 {
821 	itWriteConfigDword(info, IT8181_STANDBY, 0x0000c000);
822 
823 	// program PLL1
824 	itWriteConfigDword(info, IT8181_PLL1,
825 	                   (par->pll1_P << 16) |
826 	                   (((-par->pll1_N) & 0xff) << 8) |
827 	                   (((-par->pll1_M) & 0x3f)));
828 
829 	// PLL2 = 49.5 MHz
830 	itWriteConfigDword(info, IT8181_PLL2, 0x0002AD3A);
831 
832 	itWriteConfigDword(info, IT8181_STANDBY, 0x00000110);
833 	mdelay(25); // wait 25 msec
834 }
835 
836 /* get current video mode */
it8181fb_get_par(void * _par,struct fb_info_gen * _info)837 static void it8181fb_get_par (void *_par, struct fb_info_gen *_info)
838 {
839         struct it8181fb_par *par = (struct it8181fb_par *) _par;
840         struct it8181fb_info *info = (struct it8181fb_info *) _info;
841 
842         *par = info->current_par;
843 }
844 
845 /*
846   setmod for IT8181 chip
847 */
it8181fb_set_par(const void * _par,struct fb_info_gen * _info)848 static void it8181fb_set_par(const void *_par, struct fb_info_gen *_info)
849 {
850         struct it8181fb_par *par = (struct it8181fb_par *) _par;
851         struct it8181fb_info *info = (struct it8181fb_info *) _info;
852 
853 	dbg("%dx%dx%d", par->var.xres, par->var.yres, par->var.bits_per_pixel);
854 	dbg("%d %d %d %d %d %d %d",
855 	    par->var.pixclock,
856 	    par->var.left_margin,
857 	    par->var.right_margin,
858 	    par->var.upper_margin,
859 	    par->var.lower_margin,
860 	    par->var.hsync_len,
861 	    par->var.vsync_len);
862 
863 	/* disable cursor */
864 	writeb(0x00, info->itGuiCtrlVirt + 0x100);
865 
866 	itExtBUnlock();
867 	itExtAUnlock();
868 
869 	mdelay(25);
870 
871 	// disable display sync
872 	itWriteRegExtB(0x3c, 0x0a);
873 
874 	// Set RAM to 1M*16bit Symmetric DRAM
875 	itWriteRegExtB(0x2f,0x80);
876 
877 	// enable GUI engine registers
878 	itWriteRegExtB(0x2b,0x10);
879 
880 	// set pixel clock
881 	it8181SetPLL(par, info);
882 
883 	// Step2
884 	if (par->var.xres == 640 && par->var.yres == 480 &&
885 	    (par->var.bits_per_pixel == 8 || par->var.bits_per_pixel == 16)) {
886 		itWriteRegMisc(0xc3);
887 
888 		itWriteRegCrtc(VGA_CRTC_H_TOTAL, 0x5f);
889 		itWriteRegCrtc(VGA_CRTC_H_DISP, 0x4f);
890 		itWriteRegCrtc(VGA_CRTC_H_BLANK_START, 0x40);
891 		itWriteRegCrtc(VGA_CRTC_H_BLANK_END, 0x80);
892 		itWriteRegCrtc(VGA_CRTC_H_SYNC_START, 0x52);
893 		itWriteRegCrtc(VGA_CRTC_H_SYNC_END, 0x81);
894 		itWriteRegCrtc(VGA_CRTC_V_TOTAL, 0x0b);
895 		itWriteRegCrtc(VGA_CRTC_OVERFLOW, 0x3e);
896 		itWriteRegCrtc(VGA_CRTC_PRESET_ROW, 0x00);
897 		itWriteRegCrtc(VGA_CRTC_MAX_SCAN, 0x40);
898 		itWriteRegCrtc(VGA_CRTC_CURSOR_START, 0x00);
899 		itWriteRegCrtc(VGA_CRTC_CURSOR_END, 0x00);
900 		itWriteRegCrtc(VGA_CRTC_START_HI, 0x00);
901 		itWriteRegCrtc(VGA_CRTC_START_LO, 0x00);
902 		itWriteRegCrtc(VGA_CRTC_CURSOR_HI, 0x01);
903 		itWriteRegCrtc(VGA_CRTC_CURSOR_LO, 0x49);
904 		itWriteRegCrtc(VGA_CRTC_V_SYNC_START, 0xea);
905 		itWriteRegCrtc(VGA_CRTC_V_SYNC_END, 0x8c);
906 		itWriteRegCrtc(VGA_CRTC_V_DISP_END, 0xdf);
907 		itWriteRegCrtc(VGA_CRTC_OFFSET, 0x50);
908 		itWriteRegCrtc(VGA_CRTC_UNDERLINE, 0x00);
909 		itWriteRegCrtc(VGA_CRTC_V_BLANK_START, 0xe7);
910 		itWriteRegCrtc(VGA_CRTC_V_BLANK_END, 0x04);
911 		itWriteRegCrtc(VGA_CRTC_MODE, 0xe3);
912 		itWriteRegCrtc(VGA_CRTC_LINE_COMPARE, 0xff);
913 	} else if (par->var.xres == 800 && par->var.yres == 600 &&
914 	           (par->var.bits_per_pixel == 8 || par->var.bits_per_pixel == 16)) {
915 		itWriteRegMisc(0x03);
916 
917 		itWriteRegCrtc(VGA_CRTC_H_TOTAL, 0x07);
918 		itWriteRegCrtc(VGA_CRTC_H_DISP, 0x63);
919 		itWriteRegCrtc(VGA_CRTC_H_BLANK_START, 0x64);
920 		itWriteRegCrtc(VGA_CRTC_H_BLANK_END, 0x81);
921 		itWriteRegCrtc(VGA_CRTC_H_SYNC_START, 0x6c);
922 		itWriteRegCrtc(VGA_CRTC_H_SYNC_END, 0x18);
923 		itWriteRegCrtc(VGA_CRTC_V_TOTAL, 0x72);
924 		itWriteRegCrtc(VGA_CRTC_OVERFLOW, 0x0f);
925 		itWriteRegCrtc(VGA_CRTC_PRESET_ROW, 0x00);
926 		itWriteRegCrtc(VGA_CRTC_MAX_SCAN, 0x60);
927 		itWriteRegCrtc(VGA_CRTC_CURSOR_START, 0x00);
928 		itWriteRegCrtc(VGA_CRTC_CURSOR_END, 0x00);
929 		itWriteRegCrtc(VGA_CRTC_START_HI, 0x00);
930 		itWriteRegCrtc(VGA_CRTC_START_LO, 0x00);
931 		itWriteRegCrtc(VGA_CRTC_CURSOR_HI, 0x00);
932 		itWriteRegCrtc(VGA_CRTC_CURSOR_LO, 0xaa);
933 		itWriteRegCrtc(VGA_CRTC_V_SYNC_START, 0x59);
934 		itWriteRegCrtc(VGA_CRTC_V_SYNC_END, 0xad);
935 		itWriteRegCrtc(VGA_CRTC_V_DISP_END, 0x57);
936 		itWriteRegCrtc(VGA_CRTC_OFFSET, 0x64);
937 		itWriteRegCrtc(VGA_CRTC_UNDERLINE, 0x00);
938 		itWriteRegCrtc(VGA_CRTC_V_BLANK_START, 0x59);
939 		itWriteRegCrtc(VGA_CRTC_V_BLANK_END, 0x00);
940 		itWriteRegCrtc(VGA_CRTC_MODE, 0xe3);
941 		itWriteRegCrtc(VGA_CRTC_LINE_COMPARE, 0xff);
942 	}
943 
944 
945 	if (par->var.bits_per_pixel == 8) {
946 		if (par->var.xres == 640 && par->var.yres == 480)
947 			itWriteRegCrtc(VGA_CRTC_OFFSET, 0x28);
948 		else if (par->var.xres == 800 && par->var.yres == 600)
949 			itWriteRegCrtc(VGA_CRTC_OFFSET, 0x32);
950 	}
951 
952 	itWriteRegSEQ(VGA_SEQ_RESET, 0x03);
953 	itWriteRegExtB(0x06, 0x01);
954 	itWriteRegExtB(0x20, 0x01);
955 
956 	if (par->var.xres == 640 && par->var.yres == 480) {
957 		if (par->var.bits_per_pixel == 8)
958 			itWriteRegExtB(0x38, 0x01);
959 		else if (par->var.bits_per_pixel == 16)
960 			itWriteRegExtB(0x38, 0x03);
961 		itWriteRegExtB(0x39, 0x40);
962 	} else if (par->var.xres == 800 && par->var.yres == 600) {
963 		if (par->var.bits_per_pixel == 8)
964 			itWriteRegExtB(0x38, 0x21);
965 		else if (par->var.bits_per_pixel == 16)
966 			itWriteRegExtB(0x38, 0x23);
967 		itWriteRegExtB(0x39, 0x44);
968 	}
969 
970 	writeb(0xff, info->itMmioAddrVirt+VGA_PEL_MSK);
971 
972 	// Step3
973 	if (it8181fb_lcd) {
974 		if (par->var.xres == 640 && par->var.yres == 480 &&
975 		    (par->var.bits_per_pixel == 8 ||
976 		     par->var.bits_per_pixel == 16)) {
977 			dbg("LCD 640x480-8/16 selected");
978 			itWriteRegExtA(0x80, 0x4e);
979 			itWriteRegExtA(0x81, 0x00);
980 			itWriteRegExtA(0x82, 0x13);
981 			itWriteRegExtA(0x83, 0x00);
982 			itWriteRegExtA(0x84, 0x10);
983 			itWriteRegExtA(0x85, 0xdf);
984 			itWriteRegExtA(0x86, 0x00);
985 			itWriteRegExtA(0x87, 0x28);
986 			itWriteRegExtA(0x88, 0x00);
987 			itWriteRegExtA(0x89, 0x00);
988 			itWriteRegExtA(0x8a, 0x81);
989 			itWriteRegExtA(0x8b, 0x4e);
990 			itWriteRegExtA(0x8c, 0x00);
991 			itWriteRegExtA(0x8d, 0x2b);
992 			itWriteRegExtA(0x8e, 0x00);
993 			itWriteRegExtA(0x8f, 0x00);
994 			itWriteRegExtA(0x90, 0x01);
995 			itWriteRegExtA(0x91, 0x00);
996 			itWriteRegExtA(0x92, 0x00);
997 			itWriteRegExtA(0x93, 0x10);
998 
999 			itWriteRegExtA(0xa0, 0x23);
1000 
1001 			itWriteRegExtA(0xb0, 0x04);
1002 			itWriteRegExtA(0xb1, 0x04);
1003 			itWriteRegExtA(0xb2, 0x40);
1004 			itWriteRegExtA(0xb3, 0x40);
1005 			itWriteRegExtA(0xb4, 0x08);
1006 			itWriteRegExtA(0xb5, 0x08);
1007 			itWriteRegExtA(0xb6, 0x80);
1008 			itWriteRegExtA(0xb7, 0x80);
1009 			itWriteRegExtA(0xb8, 0x2a);
1010 			itWriteRegExtA(0xb9, 0x3b);
1011 			itWriteRegExtA(0xba, 0x6e);
1012 			itWriteRegExtA(0xbb, 0x7f);
1013 			itWriteRegExtA(0xbc, 0x80);
1014 			itWriteRegExtA(0xbd, 0x19);
1015 			itWriteRegExtA(0xbe, 0xc4);
1016 			itWriteRegExtA(0xbf, 0xd5);
1017 		} else if (par->var.xres == 800 && par->var.yres == 600 &&
1018 		           (par->var.bits_per_pixel == 8 ||
1019 			    par->var.bits_per_pixel == 16)) {
1020 			dbg("LCD 800x600-8/16 selected");
1021 			itWriteRegExtA(0x80, 0x62);
1022 			itWriteRegExtA(0x81, 0x00);
1023 			itWriteRegExtA(0x82, 0x1f);
1024 			itWriteRegExtA(0x83, 0x00);
1025 			itWriteRegExtA(0x84, 0x10);
1026 			itWriteRegExtA(0x85, 0x57);
1027 			itWriteRegExtA(0x86, 0x18);
1028 			itWriteRegExtA(0x87, 0x48);
1029 			itWriteRegExtA(0x88, 0x00);
1030 			itWriteRegExtA(0x89, 0x00);
1031 			itWriteRegExtA(0x8a, 0xf9);
1032 			itWriteRegExtA(0x8b, 0xc7);
1033 			itWriteRegExtA(0x8c, 0x00);
1034 			itWriteRegExtA(0x8d, 0x1a);
1035 			itWriteRegExtA(0x8e, 0x00);
1036 			itWriteRegExtA(0x8f, 0x00);
1037 			itWriteRegExtA(0x90, 0x41);
1038 			itWriteRegExtA(0x91, 0x00);
1039 			itWriteRegExtA(0x92, 0x00);
1040 			itWriteRegExtA(0x93, 0x10);
1041 
1042 			itWriteRegExtA(0xa0, 0x23);
1043 
1044 			itWriteRegExtA(0xb0, 0x00);
1045 			itWriteRegExtA(0xb1, 0x00);
1046 			itWriteRegExtA(0xb2, 0x00);
1047 			itWriteRegExtA(0xb3, 0x00);
1048 			itWriteRegExtA(0xb4, 0x00);
1049 			itWriteRegExtA(0xb5, 0x00);
1050 			itWriteRegExtA(0xb6, 0x00);
1051 			itWriteRegExtA(0xb7, 0x00);
1052 			itWriteRegExtA(0xb8, 0x50);
1053 			itWriteRegExtA(0xb9, 0x7b);
1054 			itWriteRegExtA(0xba, 0x8c);
1055 			itWriteRegExtA(0xbb, 0x2e);
1056 			itWriteRegExtA(0xbc, 0x14);
1057 			itWriteRegExtA(0xbd, 0xa6);
1058 			itWriteRegExtA(0xbe, 0xd9);
1059 			itWriteRegExtA(0xbf, 0xf3);
1060 		}
1061 
1062 		if (it8181fb_memory_type == 0) {
1063 			itWriteRegExtA(0xa8, 0x30);
1064 			itWriteRegExtA(0xa9, 0x3c);
1065 		} else {
1066 			itWriteRegExtA(0xa8, 0xc0);
1067 			itWriteRegExtA(0xa9, 0xe0);
1068 		}
1069 
1070 		itWriteRegExtA(0xa1, 0x01);
1071 		itWriteRegExtA(0xa2, 0x00);
1072 
1073 		itWriteRegExtA(0x9a, 0x22);
1074 		itWriteRegExtA(0x9b, 0x01);
1075 	}
1076 
1077 	// turn display sync's back on
1078 	itWriteRegExtB(0x3c, 0x00);
1079 
1080 	itExtBLock();
1081 	itExtALock();
1082 
1083 	mdelay(25);
1084 
1085 	/* this par is now current par */
1086 	info->current_par = *par;
1087 }
1088 
1089 /*
1090  * Set/Get the color of a palette entry in 8bpp mode
1091  */
1092 static inline void
do_setpalentry(unsigned regno,u8 r,u8 g,u8 b)1093 do_setpalentry(unsigned regno, u8 r, u8 g, u8 b)
1094 {
1095 	writeb((u8)regno, itMmioAddr+VGA_PEL_IW);
1096 	writeb(r, itMmioAddr+VGA_PEL_D);
1097 	writeb(g, itMmioAddr+VGA_PEL_D);
1098 	writeb(b, itMmioAddr+VGA_PEL_D);
1099 }
1100 
1101 static inline void
do_getpalentry(unsigned regno,u8 * r,u8 * g,u8 * b)1102 do_getpalentry(unsigned regno, u8* r, u8* g, u8* b)
1103 {
1104 	writeb((u8)regno, itMmioAddr+VGA_PEL_IW);
1105 	*r = readb(itMmioAddr+VGA_PEL_D);
1106 	*g = readb(itMmioAddr+VGA_PEL_D);
1107 	*b = readb(itMmioAddr+VGA_PEL_D);
1108 }
1109 
it8181fb_getcolreg(unsigned regno,unsigned * red,unsigned * green,unsigned * blue,unsigned * transp,struct fb_info * _info)1110 static int it8181fb_getcolreg(unsigned regno, unsigned *red, unsigned *green,
1111 			      unsigned *blue, unsigned *transp,
1112 			      struct fb_info *_info)
1113 {
1114 	u8 r,g,b;
1115 
1116         if (regno > 255)
1117                 return 1;
1118 
1119 	do_getpalentry(regno, &r, &g, &b);
1120 
1121         *red    = (unsigned)r << 10;
1122         *green  = (unsigned)g << 10;
1123         *blue   = (unsigned)b << 10;
1124         *transp = 0;
1125 
1126         return 0;
1127 }
1128 
it8181fb_setcolreg(unsigned regno,unsigned red,unsigned green,unsigned blue,unsigned transp,struct fb_info * _info)1129 static int it8181fb_setcolreg(unsigned regno, unsigned red, unsigned green,
1130 			      unsigned blue, unsigned transp,
1131 			      struct fb_info *_info)
1132 {
1133 	struct it8181fb_info *p = (struct it8181fb_info *) _info;
1134 	struct it8181fb_par* par = &p->current_par;
1135 
1136 	if (regno > 255)
1137 		return -EINVAL;
1138 
1139 	do_setpalentry(regno, (u8)(red>>10),
1140 		       (u8)(green>>10), (u8)(blue>>10));
1141 
1142 	switch (par->var.bits_per_pixel) {
1143 #ifdef FBCON_HAS_CFB16
1144 	case 16:
1145 		if(regno < CMAPSIZE)
1146 			fbcon_cmap.cfb16[regno] =
1147 				((red & 0xf800) >> 0) |
1148 				((green & 0xf800) >> 5) |
1149 				((blue & 0xf800) >> 11);
1150 		break;
1151 #endif
1152 #ifdef FBCON_HAS_CFB24
1153 	case 24:
1154 		if (regno < CMAPSIZE)
1155 			fbcon_cmap.cfb24[regno] =
1156 				((red & 0xff00) << 8) |
1157 				((green & 0xff00)) |
1158 				((blue & 0xff00) >> 8);
1159 		break;
1160 #endif
1161 #ifdef FBCON_HAS_CFB32
1162 	case 32:
1163 		if(regno < CMAPSIZE)
1164 			fbcon_cmap.cfb32[regno] =
1165 				((red & 0xff00) >> 8) |
1166 				((green & 0xff00)) |
1167 				((blue & 0xff00) << 8);
1168 		break;
1169 #endif
1170 	default:
1171 		break;
1172 	}
1173 
1174 	return 0;
1175 }
1176 
it8181fb_pan_display(const struct fb_var_screeninfo * var,struct fb_info_gen * info)1177 static int it8181fb_pan_display (const struct fb_var_screeninfo *var,
1178 				 struct fb_info_gen *info)
1179 {
1180 	/* not implemented */
1181 	return 0;
1182 }
1183 
1184 /*
1185  *  Initialisation
1186  */
it8181fb_init(void)1187 int it8181fb_init(void)
1188 {
1189 	struct fb_var_screeninfo var;
1190 	struct it8181fb_info *p = NULL;
1191 
1192 	fb_it8181 = p =
1193 		(struct it8181fb_info *) kmalloc(sizeof(*p), GFP_ATOMIC);
1194 	if(p==NULL)
1195 		return -ENOMEM;
1196 	memset(p, 0, sizeof(*p));
1197 
1198 #ifdef CONFIG_PCI
1199 	p->pdev = (struct pci_dev *) pci_find_device(PCI_VENDOR_ID_ITE,
1200 						     PCI_DEVICE_ID_ITE_IT8181,
1201 						     NULL);
1202 #endif
1203 	if(!p->pdev) {
1204 		u32 id = 0;
1205 		if (default_config_offset)
1206 			p->itConfigAddrVirt = (u32) ioremap(default_memory_base +
1207 			                                    default_config_offset,
1208 			                                    IT8181_CFG_SIZE);
1209 		if (p->itConfigAddrVirt)
1210 			itReadConfigDword(p, PCI_VENDOR_ID, &id);
1211 		if (!(id == (PCI_VENDOR_ID_ITE | (PCI_DEVICE_ID_ITE_IT8181 << 16))))
1212 			return -ENODEV;
1213 	}
1214 
1215 	itReadConfigDword(p, PCI_BASE_ADDRESS_0, &(p->itFbAddrPhys));
1216 	itReadConfigDword(p, PCI_BASE_ADDRESS_1, &(p->itGuiCtrlPhys));
1217 	itReadConfigDword(p, PCI_BASE_ADDRESS_2, &(p->itMmioAddrPhys));
1218 
1219 	p->itFbAddrVirt = (u32) ioremap(p->itFbAddrPhys + default_memory_base,
1220 	                                IT8181_FB_SIZE);
1221 	p->itGuiCtrlVirt = (u32) ioremap(p->itGuiCtrlPhys + default_memory_base,
1222 	                                 IT8181_GUI_SIZE);
1223 	p->itMmioAddrVirt = itMmioAddr = (u32) ioremap(p->itMmioAddrPhys +
1224 	                                               default_memory_base,
1225 	                                               IT8181_MMIO_SIZE);
1226 
1227 	info("Mmio at 0x%08x, Framebuffer at 0x%08x", itMmioAddr, p->itFbAddrVirt);
1228 
1229         /* set up a few more things, register framebuffer driver etc */
1230         p->gen.parsize = sizeof (struct it8181fb_par);
1231         p->gen.fbhw = &it8181fb_hwswitch;
1232 
1233 	strcpy(p->gen.info.modename, "ITE ");
1234 	strcat(p->gen.info.modename, it8181fb_name);
1235 	p->gen.info.changevar = NULL;
1236 	p->gen.info.node = -1;
1237 
1238 	p->gen.info.fbops = &it8181fb_ops;
1239 	p->gen.info.disp = &p->disp;
1240 	p->gen.info.switch_con = &fbgen_switch;
1241 	p->gen.info.updatevar = &fbgen_update_var;
1242 	p->gen.info.blank = &fbgen_blank;
1243 	p->gen.info.flags = FBINFO_FLAG_DEFAULT;
1244 
1245 	if(!mode_option || !fb_find_mode(&var, &p->gen.info,
1246 					 mode_option, NULL, 0, NULL, 16)) {
1247 		var = it8181_var_table[default_res];
1248 		var.bits_per_pixel = default_bpp;
1249 	}
1250 
1251         if (fbgen_do_set_var(&var, 1, &p->gen)) {
1252                 /*
1253                  * Can't use the mode from the mode db or the default
1254                  * mode - give up
1255                  */
1256                 err("boot video mode failed");
1257                 goto ret_enxio;
1258         }
1259 
1260         p->disp.var = var;
1261         fbgen_set_disp(-1, &p->gen);
1262         fbgen_install_cmap(0, &p->gen);
1263 
1264 	if (register_framebuffer(&p->gen.info) < 0) {
1265 		goto ret_enxio;
1266 	}
1267 
1268 	return 0;
1269 
1270  ret_enxio:
1271 	kfree(p);
1272 	iounmap((void *)itMmioAddr);
1273 	iounmap((void *)p->itGuiCtrlVirt);
1274 	iounmap((void *)p->itFbAddrVirt);
1275 	return -ENXIO;
1276 }
1277 
1278 #ifdef MODULE
1279 
init_module(void)1280 int init_module(void)
1281 {
1282 	return it8181fb_init();
1283 }
1284 
cleanup_module(void)1285 void cleanup_module(void)
1286 {
1287 	unregister_framebuffer(&(fb_it8181->gen.info));
1288 	iounmap((void*)itMmioAddr);
1289 	iounmap((void*)fb_it8181->itFbAddrVirt);
1290 	kfree(fb_it8181);
1291 }
1292 
1293 #else
1294 
it8181fb_setup(char * options,int * ints)1295 int it8181fb_setup(char *options, int *ints)
1296 {
1297 	char *this_opt;
1298 	int xres, cpu = 0, mod;
1299 
1300 	if (!options || !*options)
1301 		return 1;
1302 
1303 	for (this_opt = strtok(options, ","); this_opt;
1304 	     this_opt = strtok(NULL, ",")) {
1305 		if (!strncmp(this_opt, "font:", 5)) {
1306 			strcpy(fontname, this_opt+5);
1307 		} else if (!strncmp(this_opt, "bpp:", 4)) {
1308 			default_bpp = simple_strtoul(this_opt+4, NULL, 0);
1309 		} else if (!strncmp(this_opt, "xres:", 5)) {
1310 			xres = simple_strtoul(this_opt+5, NULL, 0);
1311 			if (xres == 640)
1312 				default_res = RES_640x480;
1313 			else if (xres == 800)
1314 				default_res = RES_800x600;
1315 			else if (xres == 1024)
1316 				default_res = RES_1024x768;
1317 		} else if (!strncmp(this_opt, "cpu:", 4)) {
1318 			if (!strncmp(this_opt+4, "vr4111", 6)) {
1319 				cpu = 1;
1320 				default_memory_base = 0xa000000;
1321 			} else if (!strncmp(this_opt + 4, "sh7750", 6)) {
1322 				cpu = 2;
1323 			}
1324 		} else if (!strncmp(this_opt, "mod:", 4)) {
1325 			mod = simple_strtoul(this_opt+4, NULL, 0);
1326 			if (cpu == 1) {
1327 				/* NEC VR4111 or VR4121 */
1328 				if (mod == 1)
1329 					default_memory_base += 0x800000;
1330 				default_config_offset = 0x800000 - 0x400;
1331 			} else if (cpu == 2) {
1332 				/* Hitachi SH7750 */
1333 				if (mod == 0)
1334 					default_config_offset = 0x2000000 - 0x400;
1335 				else if (mod == 1)
1336 					default_config_offset = 0x3000000 - 0x400;
1337 			}
1338 		}else if (!strncmp(this_opt, "lcd:", 4)) {
1339 			it8181fb_lcd = simple_strtoul(this_opt+4, NULL, 0);
1340 		}else if (!strncmp(this_opt, "mtype:", 6)) {
1341 			it8181fb_memory_type = simple_strtoul(this_opt+6, NULL, 0);
1342 		} else {
1343 			mode_option = this_opt;
1344 		}
1345 	}
1346 
1347 	return 0;
1348 }
1349 
1350 #endif /* MODULE */
1351