aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/sm7xx
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/staging/sm7xx
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/staging/sm7xx')
-rw-r--r--drivers/staging/sm7xx/Kconfig8
-rw-r--r--drivers/staging/sm7xx/Makefile3
-rw-r--r--drivers/staging/sm7xx/TODO9
-rw-r--r--drivers/staging/sm7xx/smtcfb.c1153
-rw-r--r--drivers/staging/sm7xx/smtcfb.h788
5 files changed, 1961 insertions, 0 deletions
diff --git a/drivers/staging/sm7xx/Kconfig b/drivers/staging/sm7xx/Kconfig
new file mode 100644
index 00000000000..315102c7fed
--- /dev/null
+++ b/drivers/staging/sm7xx/Kconfig
@@ -0,0 +1,8 @@
1config FB_SM7XX
2 tristate "Silicon Motion SM7XX Frame Buffer Support"
3 depends on FB
4 select FB_CFB_FILLRECT
5 select FB_CFB_COPYAREA
6 select FB_CFB_IMAGEBLIT
7 help
8 Frame Buffer driver for the Silicon Motion SM7XX serial graphic card.
diff --git a/drivers/staging/sm7xx/Makefile b/drivers/staging/sm7xx/Makefile
new file mode 100644
index 00000000000..f43cb910630
--- /dev/null
+++ b/drivers/staging/sm7xx/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_FB_SM7XX) += sm7xx.o
2
3sm7xx-y := smtcfb.o
diff --git a/drivers/staging/sm7xx/TODO b/drivers/staging/sm7xx/TODO
new file mode 100644
index 00000000000..7304021368c
--- /dev/null
+++ b/drivers/staging/sm7xx/TODO
@@ -0,0 +1,9 @@
1TODO:
2- Dual head support
3- 2D acceleration support
4- use kernel coding style
5- refine the code and remove unused code
6- move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c
7
8Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
9Teddy Wang <teddy.wang@siliconmotion.com.cn>.
diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c
new file mode 100644
index 00000000000..a164fc43bd8
--- /dev/null
+++ b/drivers/staging/sm7xx/smtcfb.c
@@ -0,0 +1,1153 @@
1/*
2 * Silicon Motion SM7XX frame buffer device
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Authors: Ge Wang, gewang@siliconmotion.com
6 * Boyod boyod.yang@siliconmotion.com.cn
7 *
8 * Copyright (C) 2009 Lemote, Inc.
9 * Author: Wu Zhangjin, wuzhangjin@gmail.com
10 *
11 * Copyright (C) 2011 Igalia, S.L.
12 * Author: Javier M. Mellid <jmunhoz@igalia.com>
13 *
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file COPYING in the main directory of this archive for
16 * more details.
17 *
18 * Version 0.10.26192.21.01
19 * - Add PowerPC/Big endian support
20 * - Verified on 2.6.19.2
21 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
22 *
23 * Version 0.09.2621.00.01
24 * - Only support Linux Kernel's version 2.6.21
25 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
26 *
27 * Version 0.09
28 * - Only support Linux Kernel's version 2.6.12
29 * Boyod.yang <boyod.yang@siliconmotion.com.cn>
30 */
31
32#include <linux/io.h>
33#include <linux/fb.h>
34#include <linux/pci.h>
35#include <linux/init.h>
36#include <linux/slab.h>
37#include <linux/uaccess.h>
38#include <linux/console.h>
39#include <linux/screen_info.h>
40
41#ifdef CONFIG_PM
42#include <linux/pm.h>
43#endif
44
45#include "smtcfb.h"
46
47#ifdef DEBUG
48#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
49#else
50#define smdbg(format, arg...)
51#endif
52
53struct screen_info smtc_screen_info;
54
55/*
56* Private structure
57*/
58struct smtcfb_info {
59 /*
60 * The following is a pointer to be passed into the
61 * functions below. The modules outside the main
62 * voyager.c driver have no knowledge as to what
63 * is within this structure.
64 */
65 struct fb_info fb;
66 struct display_switch *dispsw;
67 struct pci_dev *dev;
68 signed int currcon;
69
70 struct {
71 u8 red, green, blue;
72 } palette[NR_RGB];
73
74 u_int palette_size;
75};
76
77struct par_info {
78 /*
79 * Hardware
80 */
81 u16 chipID;
82 unsigned char __iomem *m_pMMIO;
83 char __iomem *m_pLFB;
84 char *m_pDPR;
85 char *m_pVPR;
86 char *m_pCPR;
87
88 u_int width;
89 u_int height;
90 u_int hz;
91 u_long BaseAddressInVRAM;
92 u8 chipRevID;
93};
94
95struct vesa_mode_table {
96 char mode_index[6];
97 u16 lfb_width;
98 u16 lfb_height;
99 u16 lfb_depth;
100};
101
102static struct vesa_mode_table vesa_mode[] = {
103 {"0x301", 640, 480, 8},
104 {"0x303", 800, 600, 8},
105 {"0x305", 1024, 768, 8},
106 {"0x307", 1280, 1024, 8},
107
108 {"0x311", 640, 480, 16},
109 {"0x314", 800, 600, 16},
110 {"0x317", 1024, 768, 16},
111 {"0x31A", 1280, 1024, 16},
112
113 {"0x312", 640, 480, 24},
114 {"0x315", 800, 600, 24},
115 {"0x318", 1024, 768, 24},
116 {"0x31B", 1280, 1024, 24},
117};
118
119char __iomem *smtc_RegBaseAddress; /* Memory Map IO starting address */
120char __iomem *smtc_VRAMBaseAddress; /* video memory starting address */
121
122static u32 colreg[17];
123static struct par_info hw; /* hardware information */
124
125u16 smtc_ChipIDs[] = {
126 0x710,
127 0x712,
128 0x720
129};
130
131#define numSMTCchipIDs ARRAY_SIZE(smtc_ChipIDs)
132
133static struct fb_var_screeninfo smtcfb_var = {
134 .xres = 1024,
135 .yres = 600,
136 .xres_virtual = 1024,
137 .yres_virtual = 600,
138 .bits_per_pixel = 16,
139 .red = {16, 8, 0},
140 .green = {8, 8, 0},
141 .blue = {0, 8, 0},
142 .activate = FB_ACTIVATE_NOW,
143 .height = -1,
144 .width = -1,
145 .vmode = FB_VMODE_NONINTERLACED,
146};
147
148static struct fb_fix_screeninfo smtcfb_fix = {
149 .id = "sm712fb",
150 .type = FB_TYPE_PACKED_PIXELS,
151 .visual = FB_VISUAL_TRUECOLOR,
152 .line_length = 800 * 3,
153 .accel = FB_ACCEL_SMI_LYNX,
154};
155
156static void sm712_set_timing(struct smtcfb_info *sfb,
157 struct par_info *ppar_info)
158{
159 int i = 0, j = 0;
160 u32 m_nScreenStride;
161
162 smdbg("\nppar_info->width = %d ppar_info->height = %d"
163 "sfb->fb.var.bits_per_pixel = %d ppar_info->hz = %d\n",
164 ppar_info->width, ppar_info->height,
165 sfb->fb.var.bits_per_pixel, ppar_info->hz);
166
167 for (j = 0; j < numVGAModes; j++) {
168 if (VGAMode[j].mmSizeX == ppar_info->width &&
169 VGAMode[j].mmSizeY == ppar_info->height &&
170 VGAMode[j].bpp == sfb->fb.var.bits_per_pixel &&
171 VGAMode[j].hz == ppar_info->hz) {
172
173 smdbg("\nVGAMode[j].mmSizeX = %d VGAMode[j].mmSizeY ="
174 "%d VGAMode[j].bpp = %d"
175 "VGAMode[j].hz=%d\n",
176 VGAMode[j].mmSizeX, VGAMode[j].mmSizeY,
177 VGAMode[j].bpp, VGAMode[j].hz);
178
179 smdbg("VGAMode index=%d\n", j);
180
181 smtc_mmiowb(0x0, 0x3c6);
182
183 smtc_seqw(0, 0x1);
184
185 smtc_mmiowb(VGAMode[j].Init_MISC, 0x3c2);
186
187 /* init SEQ register SR00 - SR04 */
188 for (i = 0; i < SIZE_SR00_SR04; i++)
189 smtc_seqw(i, VGAMode[j].Init_SR00_SR04[i]);
190
191 /* init SEQ register SR10 - SR24 */
192 for (i = 0; i < SIZE_SR10_SR24; i++)
193 smtc_seqw(i + 0x10,
194 VGAMode[j].Init_SR10_SR24[i]);
195
196 /* init SEQ register SR30 - SR75 */
197 for (i = 0; i < SIZE_SR30_SR75; i++)
198 if (((i + 0x30) != 0x62) \
199 && ((i + 0x30) != 0x6a) \
200 && ((i + 0x30) != 0x6b))
201 smtc_seqw(i + 0x30,
202 VGAMode[j].Init_SR30_SR75[i]);
203
204 /* init SEQ register SR80 - SR93 */
205 for (i = 0; i < SIZE_SR80_SR93; i++)
206 smtc_seqw(i + 0x80,
207 VGAMode[j].Init_SR80_SR93[i]);
208
209 /* init SEQ register SRA0 - SRAF */
210 for (i = 0; i < SIZE_SRA0_SRAF; i++)
211 smtc_seqw(i + 0xa0,
212 VGAMode[j].Init_SRA0_SRAF[i]);
213
214 /* init Graphic register GR00 - GR08 */
215 for (i = 0; i < SIZE_GR00_GR08; i++)
216 smtc_grphw(i, VGAMode[j].Init_GR00_GR08[i]);
217
218 /* init Attribute register AR00 - AR14 */
219 for (i = 0; i < SIZE_AR00_AR14; i++)
220 smtc_attrw(i, VGAMode[j].Init_AR00_AR14[i]);
221
222 /* init CRTC register CR00 - CR18 */
223 for (i = 0; i < SIZE_CR00_CR18; i++)
224 smtc_crtcw(i, VGAMode[j].Init_CR00_CR18[i]);
225
226 /* init CRTC register CR30 - CR4D */
227 for (i = 0; i < SIZE_CR30_CR4D; i++)
228 smtc_crtcw(i + 0x30,
229 VGAMode[j].Init_CR30_CR4D[i]);
230
231 /* init CRTC register CR90 - CRA7 */
232 for (i = 0; i < SIZE_CR90_CRA7; i++)
233 smtc_crtcw(i + 0x90,
234 VGAMode[j].Init_CR90_CRA7[i]);
235 }
236 }
237 smtc_mmiowb(0x67, 0x3c2);
238
239 /* set VPR registers */
240 writel(0x0, ppar_info->m_pVPR + 0x0C);
241 writel(0x0, ppar_info->m_pVPR + 0x40);
242
243 /* set data width */
244 m_nScreenStride =
245 (ppar_info->width * sfb->fb.var.bits_per_pixel) / 64;
246 switch (sfb->fb.var.bits_per_pixel) {
247 case 8:
248 writel(0x0, ppar_info->m_pVPR + 0x0);
249 break;
250 case 16:
251 writel(0x00020000, ppar_info->m_pVPR + 0x0);
252 break;
253 case 24:
254 writel(0x00040000, ppar_info->m_pVPR + 0x0);
255 break;
256 case 32:
257 writel(0x00030000, ppar_info->m_pVPR + 0x0);
258 break;
259 }
260 writel((u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride),
261 ppar_info->m_pVPR + 0x10);
262
263}
264
265static void sm712_setpalette(int regno, unsigned red, unsigned green,
266 unsigned blue, struct fb_info *info)
267{
268 struct par_info *cur_par = (struct par_info *)info->par;
269
270 if (cur_par->BaseAddressInVRAM)
271 /*
272 * second display palette for dual head. Enable CRT RAM, 6-bit
273 * RAM
274 */
275 smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x20);
276 else
277 /* primary display palette. Enable LCD RAM only, 6-bit RAM */
278 smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
279 smtc_mmiowb(regno, dac_reg);
280 smtc_mmiowb(red >> 10, dac_val);
281 smtc_mmiowb(green >> 10, dac_val);
282 smtc_mmiowb(blue >> 10, dac_val);
283}
284
285static void smtc_set_timing(struct smtcfb_info *sfb, struct par_info
286 *ppar_info)
287{
288 switch (ppar_info->chipID) {
289 case 0x710:
290 case 0x712:
291 case 0x720:
292 sm712_set_timing(sfb, ppar_info);
293 break;
294 }
295}
296
297/* chan_to_field
298 *
299 * convert a colour value into a field position
300 *
301 * from pxafb.c
302 */
303
304static inline unsigned int chan_to_field(unsigned int chan,
305 struct fb_bitfield *bf)
306{
307 chan &= 0xffff;
308 chan >>= 16 - bf->length;
309 return chan << bf->offset;
310}
311
312static int cfb_blank(int blank_mode, struct fb_info *info)
313{
314 /* clear DPMS setting */
315 switch (blank_mode) {
316 case FB_BLANK_UNBLANK:
317 /* Screen On: HSync: On, VSync : On */
318 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
319 smtc_seqw(0x6a, 0x16);
320 smtc_seqw(0x6b, 0x02);
321 smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
322 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
323 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
324 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
325 smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
326 break;
327 case FB_BLANK_NORMAL:
328 /* Screen Off: HSync: On, VSync : On Soft blank */
329 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
330 smtc_seqw(0x6a, 0x16);
331 smtc_seqw(0x6b, 0x02);
332 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
333 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
334 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
335 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
336 break;
337 case FB_BLANK_VSYNC_SUSPEND:
338 /* Screen On: HSync: On, VSync : Off */
339 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
340 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
341 smtc_seqw(0x6a, 0x0c);
342 smtc_seqw(0x6b, 0x02);
343 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
344 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
345 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
346 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
347 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
348 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
349 break;
350 case FB_BLANK_HSYNC_SUSPEND:
351 /* Screen On: HSync: Off, VSync : On */
352 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
353 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
354 smtc_seqw(0x6a, 0x0c);
355 smtc_seqw(0x6b, 0x02);
356 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
357 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
358 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
359 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
360 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
361 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
362 break;
363 case FB_BLANK_POWERDOWN:
364 /* Screen On: HSync: Off, VSync : Off */
365 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
366 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
367 smtc_seqw(0x6a, 0x0c);
368 smtc_seqw(0x6b, 0x02);
369 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
370 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
371 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
372 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
373 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
374 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
375 break;
376 default:
377 return -EINVAL;
378 }
379
380 return 0;
381}
382
383static int smtc_setcolreg(unsigned regno, unsigned red, unsigned green,
384 unsigned blue, unsigned trans, struct fb_info *info)
385{
386 struct smtcfb_info *sfb = (struct smtcfb_info *)info;
387 u32 val;
388
389 if (regno > 255)
390 return 1;
391
392 switch (sfb->fb.fix.visual) {
393 case FB_VISUAL_DIRECTCOLOR:
394 case FB_VISUAL_TRUECOLOR:
395 /*
396 * 16/32 bit true-colour, use pseuo-palette for 16 base color
397 */
398 if (regno < 16) {
399 if (sfb->fb.var.bits_per_pixel == 16) {
400 u32 *pal = sfb->fb.pseudo_palette;
401 val = chan_to_field(red, &sfb->fb.var.red);
402 val |= chan_to_field(green, \
403 &sfb->fb.var.green);
404 val |= chan_to_field(blue, &sfb->fb.var.blue);
405#ifdef __BIG_ENDIAN
406 pal[regno] =
407 ((red & 0xf800) >> 8) |
408 ((green & 0xe000) >> 13) |
409 ((green & 0x1c00) << 3) |
410 ((blue & 0xf800) >> 3);
411#else
412 pal[regno] = val;
413#endif
414 } else {
415 u32 *pal = sfb->fb.pseudo_palette;
416 val = chan_to_field(red, &sfb->fb.var.red);
417 val |= chan_to_field(green, \
418 &sfb->fb.var.green);
419 val |= chan_to_field(blue, &sfb->fb.var.blue);
420#ifdef __BIG_ENDIAN
421 val =
422 (val & 0xff00ff00 >> 8) |
423 (val & 0x00ff00ff << 8);
424#endif
425 pal[regno] = val;
426 }
427 }
428 break;
429
430 case FB_VISUAL_PSEUDOCOLOR:
431 /* color depth 8 bit */
432 sm712_setpalette(regno, red, green, blue, info);
433 break;
434
435 default:
436 return 1; /* unknown type */
437 }
438
439 return 0;
440
441}
442
443#ifdef __BIG_ENDIAN
444static ssize_t smtcfb_read(struct fb_info *info, char __user * buf, size_t
445 count, loff_t *ppos)
446{
447 unsigned long p = *ppos;
448
449 u32 *buffer, *dst;
450 u32 __iomem *src;
451 int c, i, cnt = 0, err = 0;
452 unsigned long total_size;
453
454 if (!info || !info->screen_base)
455 return -ENODEV;
456
457 if (info->state != FBINFO_STATE_RUNNING)
458 return -EPERM;
459
460 total_size = info->screen_size;
461
462 if (total_size == 0)
463 total_size = info->fix.smem_len;
464
465 if (p >= total_size)
466 return 0;
467
468 if (count >= total_size)
469 count = total_size;
470
471 if (count + p > total_size)
472 count = total_size - p;
473
474 buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
475 if (!buffer)
476 return -ENOMEM;
477
478 src = (u32 __iomem *) (info->screen_base + p);
479
480 if (info->fbops->fb_sync)
481 info->fbops->fb_sync(info);
482
483 while (count) {
484 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
485 dst = buffer;
486 for (i = c >> 2; i--;) {
487 *dst = fb_readl(src++);
488 *dst =
489 (*dst & 0xff00ff00 >> 8) |
490 (*dst & 0x00ff00ff << 8);
491 dst++;
492 }
493 if (c & 3) {
494 u8 *dst8 = (u8 *) dst;
495 u8 __iomem *src8 = (u8 __iomem *) src;
496
497 for (i = c & 3; i--;) {
498 if (i & 1) {
499 *dst8++ = fb_readb(++src8);
500 } else {
501 *dst8++ = fb_readb(--src8);
502 src8 += 2;
503 }
504 }
505 src = (u32 __iomem *) src8;
506 }
507
508 if (copy_to_user(buf, buffer, c)) {
509 err = -EFAULT;
510 break;
511 }
512 *ppos += c;
513 buf += c;
514 cnt += c;
515 count -= c;
516 }
517
518 kfree(buffer);
519
520 return (err) ? err : cnt;
521}
522
523static ssize_t
524smtcfb_write(struct fb_info *info, const char __user *buf, size_t count,
525 loff_t *ppos)
526{
527 unsigned long p = *ppos;
528
529 u32 *buffer, *src;
530 u32 __iomem *dst;
531 int c, i, cnt = 0, err = 0;
532 unsigned long total_size;
533
534 if (!info || !info->screen_base)
535 return -ENODEV;
536
537 if (info->state != FBINFO_STATE_RUNNING)
538 return -EPERM;
539
540 total_size = info->screen_size;
541
542 if (total_size == 0)
543 total_size = info->fix.smem_len;
544
545 if (p > total_size)
546 return -EFBIG;
547
548 if (count > total_size) {
549 err = -EFBIG;
550 count = total_size;
551 }
552
553 if (count + p > total_size) {
554 if (!err)
555 err = -ENOSPC;
556
557 count = total_size - p;
558 }
559
560 buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
561 if (!buffer)
562 return -ENOMEM;
563
564 dst = (u32 __iomem *) (info->screen_base + p);
565
566 if (info->fbops->fb_sync)
567 info->fbops->fb_sync(info);
568
569 while (count) {
570 c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
571 src = buffer;
572
573 if (copy_from_user(src, buf, c)) {
574 err = -EFAULT;
575 break;
576 }
577
578 for (i = c >> 2; i--;) {
579 fb_writel((*src & 0xff00ff00 >> 8) |
580 (*src & 0x00ff00ff << 8), dst++);
581 src++;
582 }
583 if (c & 3) {
584 u8 *src8 = (u8 *) src;
585 u8 __iomem *dst8 = (u8 __iomem *) dst;
586
587 for (i = c & 3; i--;) {
588 if (i & 1) {
589 fb_writeb(*src8++, ++dst8);
590 } else {
591 fb_writeb(*src8++, --dst8);
592 dst8 += 2;
593 }
594 }
595 dst = (u32 __iomem *) dst8;
596 }
597
598 *ppos += c;
599 buf += c;
600 cnt += c;
601 count -= c;
602 }
603
604 kfree(buffer);
605
606 return (cnt) ? cnt : err;
607}
608#endif /* ! __BIG_ENDIAN */
609
610void smtcfb_setmode(struct smtcfb_info *sfb)
611{
612 switch (sfb->fb.var.bits_per_pixel) {
613 case 32:
614 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
615 sfb->fb.fix.line_length = sfb->fb.var.xres * 4;
616 sfb->fb.var.red.length = 8;
617 sfb->fb.var.green.length = 8;
618 sfb->fb.var.blue.length = 8;
619 sfb->fb.var.red.offset = 16;
620 sfb->fb.var.green.offset = 8;
621 sfb->fb.var.blue.offset = 0;
622
623 break;
624 case 8:
625 sfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
626 sfb->fb.fix.line_length = sfb->fb.var.xres;
627 sfb->fb.var.red.offset = 5;
628 sfb->fb.var.red.length = 3;
629 sfb->fb.var.green.offset = 2;
630 sfb->fb.var.green.length = 3;
631 sfb->fb.var.blue.offset = 0;
632 sfb->fb.var.blue.length = 2;
633 break;
634 case 24:
635 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
636 sfb->fb.fix.line_length = sfb->fb.var.xres * 3;
637 sfb->fb.var.red.length = 8;
638 sfb->fb.var.green.length = 8;
639 sfb->fb.var.blue.length = 8;
640
641 sfb->fb.var.red.offset = 16;
642 sfb->fb.var.green.offset = 8;
643 sfb->fb.var.blue.offset = 0;
644
645 break;
646 case 16:
647 default:
648 sfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
649 sfb->fb.fix.line_length = sfb->fb.var.xres * 2;
650
651 sfb->fb.var.red.length = 5;
652 sfb->fb.var.green.length = 6;
653 sfb->fb.var.blue.length = 5;
654
655 sfb->fb.var.red.offset = 11;
656 sfb->fb.var.green.offset = 5;
657 sfb->fb.var.blue.offset = 0;
658
659 break;
660 }
661
662 hw.width = sfb->fb.var.xres;
663 hw.height = sfb->fb.var.yres;
664 hw.hz = 60;
665 smtc_set_timing(sfb, &hw);
666}
667
668static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
669{
670 /* sanity checks */
671 if (var->xres_virtual < var->xres)
672 var->xres_virtual = var->xres;
673
674 if (var->yres_virtual < var->yres)
675 var->yres_virtual = var->yres;
676
677 /* set valid default bpp */
678 if ((var->bits_per_pixel != 8) && (var->bits_per_pixel != 16) &&
679 (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32))
680 var->bits_per_pixel = 16;
681
682 return 0;
683}
684
685static int smtc_set_par(struct fb_info *info)
686{
687 struct smtcfb_info *sfb = (struct smtcfb_info *)info;
688
689 smtcfb_setmode(sfb);
690
691 return 0;
692}
693
694static struct fb_ops smtcfb_ops = {
695 .owner = THIS_MODULE,
696 .fb_check_var = smtc_check_var,
697 .fb_set_par = smtc_set_par,
698 .fb_setcolreg = smtc_setcolreg,
699 .fb_blank = cfb_blank,
700 .fb_fillrect = cfb_fillrect,
701 .fb_imageblit = cfb_imageblit,
702 .fb_copyarea = cfb_copyarea,
703#ifdef __BIG_ENDIAN
704 .fb_read = smtcfb_read,
705 .fb_write = smtcfb_write,
706#endif
707};
708
709/*
710 * Alloc struct smtcfb_info and assign the default value
711 */
712static struct smtcfb_info *smtc_alloc_fb_info(struct pci_dev *dev,
713 char *name)
714{
715 struct smtcfb_info *sfb;
716
717 sfb = kzalloc(sizeof(*sfb), GFP_KERNEL);
718
719 if (!sfb)
720 return NULL;
721
722 sfb->currcon = -1;
723 sfb->dev = dev;
724
725 /*** Init sfb->fb with default value ***/
726 sfb->fb.flags = FBINFO_FLAG_DEFAULT;
727 sfb->fb.fbops = &smtcfb_ops;
728 sfb->fb.var = smtcfb_var;
729 sfb->fb.fix = smtcfb_fix;
730
731 strcpy(sfb->fb.fix.id, name);
732
733 sfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
734 sfb->fb.fix.type_aux = 0;
735 sfb->fb.fix.xpanstep = 0;
736 sfb->fb.fix.ypanstep = 0;
737 sfb->fb.fix.ywrapstep = 0;
738 sfb->fb.fix.accel = FB_ACCEL_SMI_LYNX;
739
740 sfb->fb.var.nonstd = 0;
741 sfb->fb.var.activate = FB_ACTIVATE_NOW;
742 sfb->fb.var.height = -1;
743 sfb->fb.var.width = -1;
744 /* text mode acceleration */
745 sfb->fb.var.accel_flags = FB_ACCELF_TEXT;
746 sfb->fb.var.vmode = FB_VMODE_NONINTERLACED;
747 sfb->fb.par = &hw;
748 sfb->fb.pseudo_palette = colreg;
749
750 return sfb;
751}
752
753/*
754 * Unmap in the memory mapped IO registers
755 */
756
757static void smtc_unmap_mmio(struct smtcfb_info *sfb)
758{
759 if (sfb && smtc_RegBaseAddress)
760 smtc_RegBaseAddress = NULL;
761}
762
763/*
764 * Map in the screen memory
765 */
766
767static int smtc_map_smem(struct smtcfb_info *sfb,
768 struct pci_dev *dev, u_long smem_len)
769{
770 if (sfb->fb.var.bits_per_pixel == 32) {
771#ifdef __BIG_ENDIAN
772 sfb->fb.fix.smem_start = pci_resource_start(dev, 0)
773 + 0x800000;
774#else
775 sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
776#endif
777 } else {
778 sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
779 }
780
781 sfb->fb.fix.smem_len = smem_len;
782
783 sfb->fb.screen_base = smtc_VRAMBaseAddress;
784
785 if (!sfb->fb.screen_base) {
786 printk(KERN_ERR "%s: unable to map screen memory\n",
787 sfb->fb.fix.id);
788 return -ENOMEM;
789 }
790
791 return 0;
792}
793
794/*
795 * Unmap in the screen memory
796 *
797 */
798static void smtc_unmap_smem(struct smtcfb_info *sfb)
799{
800 if (sfb && sfb->fb.screen_base) {
801 iounmap(sfb->fb.screen_base);
802 sfb->fb.screen_base = NULL;
803 }
804}
805
806/*
807 * We need to wake up the LynxEM+, and make sure its in linear memory mode.
808 */
809static inline void sm7xx_init_hw(void)
810{
811 outb_p(0x18, 0x3c4);
812 outb_p(0x11, 0x3c5);
813}
814
815static void smtc_free_fb_info(struct smtcfb_info *sfb)
816{
817 if (sfb) {
818 fb_alloc_cmap(&sfb->fb.cmap, 0, 0);
819 kfree(sfb);
820 }
821}
822
823/*
824 * sm712vga_setup - process command line options, get vga parameter
825 * @options: string of options
826 * Returns zero.
827 *
828 */
829static int __init sm712vga_setup(char *options)
830{
831 int index;
832
833 if (!options || !*options) {
834 smdbg("\n No vga parameter\n");
835 return -EINVAL;
836 }
837
838 smtc_screen_info.lfb_width = 0;
839 smtc_screen_info.lfb_height = 0;
840 smtc_screen_info.lfb_depth = 0;
841
842 smdbg("\nsm712vga_setup = %s\n", options);
843
844 for (index = 0;
845 index < ARRAY_SIZE(vesa_mode);
846 index++) {
847 if (strstr(options, vesa_mode[index].mode_index)) {
848 smtc_screen_info.lfb_width = vesa_mode[index].lfb_width;
849 smtc_screen_info.lfb_height =
850 vesa_mode[index].lfb_height;
851 smtc_screen_info.lfb_depth = vesa_mode[index].lfb_depth;
852 return 0;
853 }
854 }
855
856 return -1;
857}
858__setup("vga=", sm712vga_setup);
859
860/* Jason (08/13/2009)
861 * Original init function changed to probe method to be used by pci_drv
862 * process used to detect chips replaced with kernel process in pci_drv
863 */
864static int __devinit smtcfb_pci_probe(struct pci_dev *pdev,
865 const struct pci_device_id *ent)
866{
867 struct smtcfb_info *sfb;
868 u_long smem_size = 0x00800000; /* default 8MB */
869 char name[16];
870 int err;
871 unsigned long pFramebufferPhysical;
872
873 printk(KERN_INFO
874 "Silicon Motion display driver " SMTC_LINUX_FB_VERSION "\n");
875
876 err = pci_enable_device(pdev); /* enable SMTC chip */
877 if (err)
878 return err;
879
880 hw.chipID = ent->device;
881 sprintf(name, "sm%Xfb", hw.chipID);
882
883 sfb = smtc_alloc_fb_info(pdev, name);
884
885 if (!sfb)
886 goto failed_free;
887 /* Jason (08/13/2009)
888 * Store fb_info to be further used when suspending and resuming
889 */
890 pci_set_drvdata(pdev, sfb);
891
892 sm7xx_init_hw();
893
894 /*get mode parameter from smtc_screen_info */
895 if (smtc_screen_info.lfb_width != 0) {
896 sfb->fb.var.xres = smtc_screen_info.lfb_width;
897 sfb->fb.var.yres = smtc_screen_info.lfb_height;
898 sfb->fb.var.bits_per_pixel = smtc_screen_info.lfb_depth;
899 } else {
900 /* default resolution 1024x600 16bit mode */
901 sfb->fb.var.xres = SCREEN_X_RES;
902 sfb->fb.var.yres = SCREEN_Y_RES;
903 sfb->fb.var.bits_per_pixel = SCREEN_BPP;
904 }
905
906#ifdef __BIG_ENDIAN
907 if (sfb->fb.var.bits_per_pixel == 24)
908 sfb->fb.var.bits_per_pixel = (smtc_screen_info.lfb_depth = 32);
909#endif
910 /* Map address and memory detection */
911 pFramebufferPhysical = pci_resource_start(pdev, 0);
912 pci_read_config_byte(pdev, PCI_REVISION_ID, &hw.chipRevID);
913
914 switch (hw.chipID) {
915 case 0x710:
916 case 0x712:
917 sfb->fb.fix.mmio_start = pFramebufferPhysical + 0x00400000;
918 sfb->fb.fix.mmio_len = 0x00400000;
919 smem_size = SM712_VIDEOMEMORYSIZE;
920#ifdef __BIG_ENDIAN
921 hw.m_pLFB = (smtc_VRAMBaseAddress =
922 ioremap(pFramebufferPhysical, 0x00c00000));
923#else
924 hw.m_pLFB = (smtc_VRAMBaseAddress =
925 ioremap(pFramebufferPhysical, 0x00800000));
926#endif
927 hw.m_pMMIO = (smtc_RegBaseAddress =
928 smtc_VRAMBaseAddress + 0x00700000);
929 hw.m_pDPR = smtc_VRAMBaseAddress + 0x00408000;
930 hw.m_pVPR = hw.m_pLFB + 0x0040c000;
931#ifdef __BIG_ENDIAN
932 if (sfb->fb.var.bits_per_pixel == 32) {
933 smtc_VRAMBaseAddress += 0x800000;
934 hw.m_pLFB += 0x800000;
935 printk(KERN_INFO
936 "\nsmtc_VRAMBaseAddress=%p hw.m_pLFB=%p\n",
937 smtc_VRAMBaseAddress, hw.m_pLFB);
938 }
939#endif
940 if (!smtc_RegBaseAddress) {
941 printk(KERN_ERR
942 "%s: unable to map memory mapped IO\n",
943 sfb->fb.fix.id);
944 err = -ENOMEM;
945 goto failed_fb;
946 }
947
948 /* set MCLK = 14.31818 * (0x16 / 0x2) */
949 smtc_seqw(0x6a, 0x16);
950 smtc_seqw(0x6b, 0x02);
951 smtc_seqw(0x62, 0x3e);
952 /* enable PCI burst */
953 smtc_seqw(0x17, 0x20);
954 /* enable word swap */
955#ifdef __BIG_ENDIAN
956 if (sfb->fb.var.bits_per_pixel == 32)
957 smtc_seqw(0x17, 0x30);
958#endif
959 break;
960 case 0x720:
961 sfb->fb.fix.mmio_start = pFramebufferPhysical;
962 sfb->fb.fix.mmio_len = 0x00200000;
963 smem_size = SM722_VIDEOMEMORYSIZE;
964 hw.m_pDPR = ioremap(pFramebufferPhysical, 0x00a00000);
965 hw.m_pLFB = (smtc_VRAMBaseAddress =
966 hw.m_pDPR + 0x00200000);
967 hw.m_pMMIO = (smtc_RegBaseAddress =
968 hw.m_pDPR + 0x000c0000);
969 hw.m_pVPR = hw.m_pDPR + 0x800;
970
971 smtc_seqw(0x62, 0xff);
972 smtc_seqw(0x6a, 0x0d);
973 smtc_seqw(0x6b, 0x02);
974 break;
975 default:
976 printk(KERN_ERR
977 "No valid Silicon Motion display chip was detected!\n");
978
979 goto failed_fb;
980 }
981
982 /* can support 32 bpp */
983 if (15 == sfb->fb.var.bits_per_pixel)
984 sfb->fb.var.bits_per_pixel = 16;
985
986 sfb->fb.var.xres_virtual = sfb->fb.var.xres;
987 sfb->fb.var.yres_virtual = sfb->fb.var.yres;
988 err = smtc_map_smem(sfb, pdev, smem_size);
989 if (err)
990 goto failed;
991
992 smtcfb_setmode(sfb);
993 /* Primary display starting from 0 position */
994 hw.BaseAddressInVRAM = 0;
995 sfb->fb.par = &hw;
996
997 err = register_framebuffer(&sfb->fb);
998 if (err < 0)
999 goto failed;
1000
1001 printk(KERN_INFO "Silicon Motion SM%X Rev%X primary display mode"
1002 "%dx%d-%d Init Complete.\n", hw.chipID, hw.chipRevID,
1003 sfb->fb.var.xres, sfb->fb.var.yres,
1004 sfb->fb.var.bits_per_pixel);
1005
1006 return 0;
1007
1008failed:
1009 printk(KERN_ERR "Silicon Motion, Inc. primary display init fail\n");
1010
1011 smtc_unmap_smem(sfb);
1012 smtc_unmap_mmio(sfb);
1013failed_fb:
1014 smtc_free_fb_info(sfb);
1015
1016failed_free:
1017 pci_disable_device(pdev);
1018
1019 return err;
1020}
1021
1022
1023/* Jason (08/11/2009) PCI_DRV wrapper essential structs */
1024static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = {
1025 {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1026 {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1027 {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1028 {0,}
1029};
1030
1031
1032/* Jason (08/14/2009)
1033 * do some clean up when the driver module is removed
1034 */
1035static void __devexit smtcfb_pci_remove(struct pci_dev *pdev)
1036{
1037 struct smtcfb_info *sfb;
1038
1039 sfb = pci_get_drvdata(pdev);
1040 pci_set_drvdata(pdev, NULL);
1041 smtc_unmap_smem(sfb);
1042 smtc_unmap_mmio(sfb);
1043 unregister_framebuffer(&sfb->fb);
1044 smtc_free_fb_info(sfb);
1045}
1046
1047#ifdef CONFIG_PM
1048static int smtcfb_pci_suspend(struct device *device)
1049{
1050 struct pci_dev *pdev = to_pci_dev(device);
1051 struct smtcfb_info *sfb;
1052
1053 sfb = pci_get_drvdata(pdev);
1054
1055 /* set the hw in sleep mode use externel clock and self memory refresh
1056 * so that we can turn off internal PLLs later on
1057 */
1058 smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
1059 smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
1060
1061 console_lock();
1062 fb_set_suspend(&sfb->fb, 1);
1063 console_unlock();
1064
1065 /* additionally turn off all function blocks including internal PLLs */
1066 smtc_seqw(0x21, 0xff);
1067
1068 return 0;
1069}
1070
1071static int smtcfb_pci_resume(struct device *device)
1072{
1073 struct pci_dev *pdev = to_pci_dev(device);
1074 struct smtcfb_info *sfb;
1075
1076 sfb = pci_get_drvdata(pdev);
1077
1078 /* reinit hardware */
1079 sm7xx_init_hw();
1080 switch (hw.chipID) {
1081 case 0x710:
1082 case 0x712:
1083 /* set MCLK = 14.31818 * (0x16 / 0x2) */
1084 smtc_seqw(0x6a, 0x16);
1085 smtc_seqw(0x6b, 0x02);
1086 smtc_seqw(0x62, 0x3e);
1087 /* enable PCI burst */
1088 smtc_seqw(0x17, 0x20);
1089#ifdef __BIG_ENDIAN
1090 if (sfb->fb.var.bits_per_pixel == 32)
1091 smtc_seqw(0x17, 0x30);
1092#endif
1093 break;
1094 case 0x720:
1095 smtc_seqw(0x62, 0xff);
1096 smtc_seqw(0x6a, 0x0d);
1097 smtc_seqw(0x6b, 0x02);
1098 break;
1099 }
1100
1101 smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
1102 smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
1103
1104 smtcfb_setmode(sfb);
1105
1106 console_lock();
1107 fb_set_suspend(&sfb->fb, 0);
1108 console_unlock();
1109
1110 return 0;
1111}
1112
1113static const struct dev_pm_ops sm7xx_pm_ops = {
1114 .suspend = smtcfb_pci_suspend,
1115 .resume = smtcfb_pci_resume,
1116 .freeze = smtcfb_pci_suspend,
1117 .thaw = smtcfb_pci_resume,
1118 .poweroff = smtcfb_pci_suspend,
1119 .restore = smtcfb_pci_resume,
1120};
1121
1122#define SM7XX_PM_OPS (&sm7xx_pm_ops)
1123
1124#else /* !CONFIG_PM */
1125
1126#define SM7XX_PM_OPS NULL
1127
1128#endif /* !CONFIG_PM */
1129
1130static struct pci_driver smtcfb_driver = {
1131 .name = "smtcfb",
1132 .id_table = smtcfb_pci_table,
1133 .probe = smtcfb_pci_probe,
1134 .remove = __devexit_p(smtcfb_pci_remove),
1135 .driver.pm = SM7XX_PM_OPS,
1136};
1137
1138static int __init smtcfb_init(void)
1139{
1140 return pci_register_driver(&smtcfb_driver);
1141}
1142
1143static void __exit smtcfb_exit(void)
1144{
1145 pci_unregister_driver(&smtcfb_driver);
1146}
1147
1148module_init(smtcfb_init);
1149module_exit(smtcfb_exit);
1150
1151MODULE_AUTHOR("Siliconmotion ");
1152MODULE_DESCRIPTION("Framebuffer driver for SMI Graphic Cards");
1153MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sm7xx/smtcfb.h b/drivers/staging/sm7xx/smtcfb.h
new file mode 100644
index 00000000000..c5e6989e65a
--- /dev/null
+++ b/drivers/staging/sm7xx/smtcfb.h
@@ -0,0 +1,788 @@
1/*
2 * Silicon Motion SM712 frame buffer device
3 *
4 * Copyright (C) 2006 Silicon Motion Technology Corp.
5 * Authors: Ge Wang, gewang@siliconmotion.com
6 * Boyod boyod.yang@siliconmotion.com.cn
7 *
8 * Copyright (C) 2009 Lemote, Inc.
9 * Author: Wu Zhangjin, wuzhangjin@gmail.com
10 *
11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive for
13 * more details.
14 */
15
16#define SMTC_LINUX_FB_VERSION "version 0.11.2619.21.01 July 27, 2008"
17
18#define NR_PALETTE 256
19#define NR_RGB 2
20
21#define FB_ACCEL_SMI_LYNX 88
22
23#ifdef __BIG_ENDIAN
24#define PC_VGA 0
25#else
26#define PC_VGA 1
27#endif
28
29#define SCREEN_X_RES 1024
30#define SCREEN_Y_RES 600
31#define SCREEN_BPP 16
32
33/*Assume SM712 graphics chip has 4MB VRAM */
34#define SM712_VIDEOMEMORYSIZE 0x00400000
35/*Assume SM722 graphics chip has 8MB VRAM */
36#define SM722_VIDEOMEMORYSIZE 0x00800000
37
38#define dac_reg (0x3c8)
39#define dac_val (0x3c9)
40
41extern char *smtc_RegBaseAddress;
42#define smtc_mmiowb(dat, reg) writeb(dat, smtc_RegBaseAddress + reg)
43#define smtc_mmioww(dat, reg) writew(dat, smtc_RegBaseAddress + reg)
44#define smtc_mmiowl(dat, reg) writel(dat, smtc_RegBaseAddress + reg)
45
46#define smtc_mmiorb(reg) readb(smtc_RegBaseAddress + reg)
47#define smtc_mmiorw(reg) readw(smtc_RegBaseAddress + reg)
48#define smtc_mmiorl(reg) readl(smtc_RegBaseAddress + reg)
49
50#define SIZE_SR00_SR04 (0x04 - 0x00 + 1)
51#define SIZE_SR10_SR24 (0x24 - 0x10 + 1)
52#define SIZE_SR30_SR75 (0x75 - 0x30 + 1)
53#define SIZE_SR80_SR93 (0x93 - 0x80 + 1)
54#define SIZE_SRA0_SRAF (0xAF - 0xA0 + 1)
55#define SIZE_GR00_GR08 (0x08 - 0x00 + 1)
56#define SIZE_AR00_AR14 (0x14 - 0x00 + 1)
57#define SIZE_CR00_CR18 (0x18 - 0x00 + 1)
58#define SIZE_CR30_CR4D (0x4D - 0x30 + 1)
59#define SIZE_CR90_CRA7 (0xA7 - 0x90 + 1)
60#define SIZE_VPR (0x6C + 1)
61#define SIZE_DPR (0x44 + 1)
62
63static inline void smtc_crtcw(int reg, int val)
64{
65 smtc_mmiowb(reg, 0x3d4);
66 smtc_mmiowb(val, 0x3d5);
67}
68
69static inline unsigned int smtc_crtcr(int reg)
70{
71 smtc_mmiowb(reg, 0x3d4);
72 return smtc_mmiorb(0x3d5);
73}
74
75static inline void smtc_grphw(int reg, int val)
76{
77 smtc_mmiowb(reg, 0x3ce);
78 smtc_mmiowb(val, 0x3cf);
79}
80
81static inline unsigned int smtc_grphr(int reg)
82{
83 smtc_mmiowb(reg, 0x3ce);
84 return smtc_mmiorb(0x3cf);
85}
86
87static inline void smtc_attrw(int reg, int val)
88{
89 smtc_mmiorb(0x3da);
90 smtc_mmiowb(reg, 0x3c0);
91 smtc_mmiorb(0x3c1);
92 smtc_mmiowb(val, 0x3c0);
93}
94
95static inline void smtc_seqw(int reg, int val)
96{
97 smtc_mmiowb(reg, 0x3c4);
98 smtc_mmiowb(val, 0x3c5);
99}
100
101static inline unsigned int smtc_seqr(int reg)
102{
103 smtc_mmiowb(reg, 0x3c4);
104 return smtc_mmiorb(0x3c5);
105}
106
107/* The next structure holds all information relevant for a specific video mode.
108 */
109
110struct ModeInit {
111 int mmSizeX;
112 int mmSizeY;
113 int bpp;
114 int hz;
115 unsigned char Init_MISC;
116 unsigned char Init_SR00_SR04[SIZE_SR00_SR04];
117 unsigned char Init_SR10_SR24[SIZE_SR10_SR24];
118 unsigned char Init_SR30_SR75[SIZE_SR30_SR75];
119 unsigned char Init_SR80_SR93[SIZE_SR80_SR93];
120 unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF];
121 unsigned char Init_GR00_GR08[SIZE_GR00_GR08];
122 unsigned char Init_AR00_AR14[SIZE_AR00_AR14];
123 unsigned char Init_CR00_CR18[SIZE_CR00_CR18];
124 unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D];
125 unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7];
126};
127
128/**********************************************************************
129 SM712 Mode table.
130 **********************************************************************/
131struct ModeInit VGAMode[] = {
132 {
133 /* mode#0: 640 x 480 16Bpp 60Hz */
134 640, 480, 16, 60,
135 /* Init_MISC */
136 0xE3,
137 { /* Init_SR0_SR4 */
138 0x03, 0x01, 0x0F, 0x00, 0x0E,
139 },
140 { /* Init_SR10_SR24 */
141 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
142 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0xC4, 0x30, 0x02, 0x01, 0x01,
144 },
145 { /* Init_SR30_SR75 */
146 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
147 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
148 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
149 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
150 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
151 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
152 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
153 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
154 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
155 },
156 { /* Init_SR80_SR93 */
157 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
158 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
159 0x00, 0x00, 0x00, 0x00,
160 },
161 { /* Init_SRA0_SRAF */
162 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
163 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
164 },
165 { /* Init_GR00_GR08 */
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
167 0xFF,
168 },
169 { /* Init_AR00_AR14 */
170 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
171 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
172 0x41, 0x00, 0x0F, 0x00, 0x00,
173 },
174 { /* Init_CR00_CR18 */
175 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
176 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
178 0xFF,
179 },
180 { /* Init_CR30_CR4D */
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
182 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
183 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
184 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
185 },
186 { /* Init_CR90_CRA7 */
187 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
188 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
189 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
190 },
191 },
192 {
193 /* mode#1: 640 x 480 24Bpp 60Hz */
194 640, 480, 24, 60,
195 /* Init_MISC */
196 0xE3,
197 { /* Init_SR0_SR4 */
198 0x03, 0x01, 0x0F, 0x00, 0x0E,
199 },
200 { /* Init_SR10_SR24 */
201 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
202 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0xC4, 0x30, 0x02, 0x01, 0x01,
204 },
205 { /* Init_SR30_SR75 */
206 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
207 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
208 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
209 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
210 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
211 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
212 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
213 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
214 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
215 },
216 { /* Init_SR80_SR93 */
217 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
218 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
219 0x00, 0x00, 0x00, 0x00,
220 },
221 { /* Init_SRA0_SRAF */
222 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
223 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
224 },
225 { /* Init_GR00_GR08 */
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
227 0xFF,
228 },
229 { /* Init_AR00_AR14 */
230 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
231 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
232 0x41, 0x00, 0x0F, 0x00, 0x00,
233 },
234 { /* Init_CR00_CR18 */
235 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
236 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
238 0xFF,
239 },
240 { /* Init_CR30_CR4D */
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
242 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
243 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
244 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
245 },
246 { /* Init_CR90_CRA7 */
247 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
248 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
249 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
250 },
251 },
252 {
253 /* mode#0: 640 x 480 32Bpp 60Hz */
254 640, 480, 32, 60,
255 /* Init_MISC */
256 0xE3,
257 { /* Init_SR0_SR4 */
258 0x03, 0x01, 0x0F, 0x00, 0x0E,
259 },
260 { /* Init_SR10_SR24 */
261 0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
262 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0xC4, 0x30, 0x02, 0x01, 0x01,
264 },
265 { /* Init_SR30_SR75 */
266 0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
267 0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
268 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
269 0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
270 0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
271 0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
272 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
273 0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
274 0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
275 },
276 { /* Init_SR80_SR93 */
277 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
278 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
279 0x00, 0x00, 0x00, 0x00,
280 },
281 { /* Init_SRA0_SRAF */
282 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
283 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
284 },
285 { /* Init_GR00_GR08 */
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
287 0xFF,
288 },
289 { /* Init_AR00_AR14 */
290 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
291 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
292 0x41, 0x00, 0x0F, 0x00, 0x00,
293 },
294 { /* Init_CR00_CR18 */
295 0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
296 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
298 0xFF,
299 },
300 { /* Init_CR30_CR4D */
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
302 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
303 0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
304 0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
305 },
306 { /* Init_CR90_CRA7 */
307 0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
308 0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
309 0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
310 },
311 },
312
313 { /* mode#2: 800 x 600 16Bpp 60Hz */
314 800, 600, 16, 60,
315 /* Init_MISC */
316 0x2B,
317 { /* Init_SR0_SR4 */
318 0x03, 0x01, 0x0F, 0x03, 0x0E,
319 },
320 { /* Init_SR10_SR24 */
321 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
322 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0xC4, 0x30, 0x02, 0x01, 0x01,
324 },
325 { /* Init_SR30_SR75 */
326 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
327 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
328 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
329 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
330 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
331 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
332 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
333 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
334 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
335 },
336 { /* Init_SR80_SR93 */
337 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
338 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
339 0x00, 0x00, 0x00, 0x00,
340 },
341 { /* Init_SRA0_SRAF */
342 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
343 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
344 },
345 { /* Init_GR00_GR08 */
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
347 0xFF,
348 },
349 { /* Init_AR00_AR14 */
350 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
351 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
352 0x41, 0x00, 0x0F, 0x00, 0x00,
353 },
354 { /* Init_CR00_CR18 */
355 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
356 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
358 0xFF,
359 },
360 { /* Init_CR30_CR4D */
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
362 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
363 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
364 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
365 },
366 { /* Init_CR90_CRA7 */
367 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
368 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
369 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
370 },
371 },
372 { /* mode#3: 800 x 600 24Bpp 60Hz */
373 800, 600, 24, 60,
374 0x2B,
375 { /* Init_SR0_SR4 */
376 0x03, 0x01, 0x0F, 0x03, 0x0E,
377 },
378 { /* Init_SR10_SR24 */
379 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
380 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0xC4, 0x30, 0x02, 0x01, 0x01,
382 },
383 { /* Init_SR30_SR75 */
384 0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
385 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
386 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
387 0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
388 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
389 0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
390 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
391 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
392 0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
393 },
394 { /* Init_SR80_SR93 */
395 0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
396 0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
397 0x00, 0x00, 0x00, 0x00,
398 },
399 { /* Init_SRA0_SRAF */
400 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
401 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
402 },
403 { /* Init_GR00_GR08 */
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
405 0xFF,
406 },
407 { /* Init_AR00_AR14 */
408 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
409 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
410 0x41, 0x00, 0x0F, 0x00, 0x00,
411 },
412 { /* Init_CR00_CR18 */
413 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
414 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
416 0xFF,
417 },
418 { /* Init_CR30_CR4D */
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
420 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
421 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
422 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
423 },
424 { /* Init_CR90_CRA7 */
425 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
426 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
427 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
428 },
429 },
430 { /* mode#7: 800 x 600 32Bpp 60Hz */
431 800, 600, 32, 60,
432 /* Init_MISC */
433 0x2B,
434 { /* Init_SR0_SR4 */
435 0x03, 0x01, 0x0F, 0x03, 0x0E,
436 },
437 { /* Init_SR10_SR24 */
438 0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
439 0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0xC4, 0x30, 0x02, 0x01, 0x01,
441 },
442 { /* Init_SR30_SR75 */
443 0x34, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
444 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
445 0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
446 0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
447 0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
448 0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
449 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
450 0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
451 0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
452 },
453 { /* Init_SR80_SR93 */
454 0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
455 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
456 0x00, 0x00, 0x00, 0x00,
457 },
458 { /* Init_SRA0_SRAF */
459 0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
460 0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
461 },
462 { /* Init_GR00_GR08 */
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
464 0xFF,
465 },
466 { /* Init_AR00_AR14 */
467 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
468 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
469 0x41, 0x00, 0x0F, 0x00, 0x00,
470 },
471 { /* Init_CR00_CR18 */
472 0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
473 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
475 0xFF,
476 },
477 { /* Init_CR30_CR4D */
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
479 0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
480 0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
481 0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
482 },
483 { /* Init_CR90_CRA7 */
484 0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
485 0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
486 0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
487 },
488 },
489 /* We use 1024x768 table to light 1024x600 panel for lemote */
490 { /* mode#4: 1024 x 600 16Bpp 60Hz */
491 1024, 600, 16, 60,
492 /* Init_MISC */
493 0xEB,
494 { /* Init_SR0_SR4 */
495 0x03, 0x01, 0x0F, 0x00, 0x0E,
496 },
497 { /* Init_SR10_SR24 */
498 0xC8, 0x40, 0x14, 0x60, 0x00, 0x0A, 0x17, 0x20,
499 0x51, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0xC4, 0x30, 0x02, 0x00, 0x01,
501 },
502 { /* Init_SR30_SR75 */
503 0x22, 0x03, 0x24, 0x09, 0xC0, 0x22, 0x22, 0x22,
504 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x03, 0xFF,
505 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
506 0x20, 0x0C, 0x44, 0x20, 0x00, 0x22, 0x22, 0x22,
507 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
508 0x00, 0x60, 0x59, 0x22, 0x22, 0x00, 0x00, 0x22,
509 0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
510 0x50, 0x03, 0x16, 0x02, 0x0D, 0x82, 0x09, 0x02,
511 0x04, 0x45, 0x3F, 0x30, 0x40, 0x20,
512 },
513 { /* Init_SR80_SR93 */
514 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
515 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
516 0x00, 0x00, 0x00, 0x00,
517 },
518 { /* Init_SRA0_SRAF */
519 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
520 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
521 },
522 { /* Init_GR00_GR08 */
523 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
524 0xFF,
525 },
526 { /* Init_AR00_AR14 */
527 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
528 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
529 0x41, 0x00, 0x0F, 0x00, 0x00,
530 },
531 { /* Init_CR00_CR18 */
532 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
533 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
535 0xFF,
536 },
537 { /* Init_CR30_CR4D */
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
539 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
540 0xA3, 0x7F, 0x00, 0x82, 0x0b, 0x6f, 0x57, 0x00,
541 0x5c, 0x0f, 0xE0, 0xe0, 0x7F, 0x57,
542 },
543 { /* Init_CR90_CRA7 */
544 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
545 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
546 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
547 },
548 },
549 { /* mode#5: 1024 x 768 24Bpp 60Hz */
550 1024, 768, 24, 60,
551 /* Init_MISC */
552 0xEB,
553 { /* Init_SR0_SR4 */
554 0x03, 0x01, 0x0F, 0x03, 0x0E,
555 },
556 { /* Init_SR10_SR24 */
557 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
558 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0xC4, 0x30, 0x02, 0x01, 0x01,
560 },
561 { /* Init_SR30_SR75 */
562 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
563 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
564 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
565 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
566 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
567 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
568 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
569 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
570 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
571 },
572 { /* Init_SR80_SR93 */
573 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
574 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
575 0x00, 0x00, 0x00, 0x00,
576 },
577 { /* Init_SRA0_SRAF */
578 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
579 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
580 },
581 { /* Init_GR00_GR08 */
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
583 0xFF,
584 },
585 { /* Init_AR00_AR14 */
586 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
587 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
588 0x41, 0x00, 0x0F, 0x00, 0x00,
589 },
590 { /* Init_CR00_CR18 */
591 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
592 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
594 0xFF,
595 },
596 { /* Init_CR30_CR4D */
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
598 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
599 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
600 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
601 },
602 { /* Init_CR90_CRA7 */
603 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
604 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
605 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
606 },
607 },
608 { /* mode#4: 1024 x 768 32Bpp 60Hz */
609 1024, 768, 32, 60,
610 /* Init_MISC */
611 0xEB,
612 { /* Init_SR0_SR4 */
613 0x03, 0x01, 0x0F, 0x03, 0x0E,
614 },
615 { /* Init_SR10_SR24 */
616 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
617 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0xC4, 0x32, 0x02, 0x01, 0x01,
619 },
620 { /* Init_SR30_SR75 */
621 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
622 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
623 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
624 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
625 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
626 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
627 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
628 0x50, 0x03, 0x74, 0x14, 0x3B, 0x0D, 0x09, 0x02,
629 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
630 },
631 { /* Init_SR80_SR93 */
632 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
633 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
634 0x00, 0x00, 0x00, 0x00,
635 },
636 { /* Init_SRA0_SRAF */
637 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
638 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
639 },
640 { /* Init_GR00_GR08 */
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
642 0xFF,
643 },
644 { /* Init_AR00_AR14 */
645 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
646 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
647 0x41, 0x00, 0x0F, 0x00, 0x00,
648 },
649 { /* Init_CR00_CR18 */
650 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
651 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
653 0xFF,
654 },
655 { /* Init_CR30_CR4D */
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
657 0x00, 0x00, 0x00, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
658 0xA3, 0x7F, 0x00, 0x86, 0x15, 0x24, 0xFF, 0x00,
659 0x01, 0x07, 0xE5, 0x20, 0x7F, 0xFF,
660 },
661 { /* Init_CR90_CRA7 */
662 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
663 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
664 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
665 },
666 },
667 { /* mode#6: 320 x 240 16Bpp 60Hz */
668 320, 240, 16, 60,
669 /* Init_MISC */
670 0xEB,
671 { /* Init_SR0_SR4 */
672 0x03, 0x01, 0x0F, 0x03, 0x0E,
673 },
674 { /* Init_SR10_SR24 */
675 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
676 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
677 0xC4, 0x32, 0x02, 0x01, 0x01,
678 },
679 { /* Init_SR30_SR75 */
680 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
681 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
682 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
683 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
684 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
685 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
686 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
687 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
688 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
689 },
690 { /* Init_SR80_SR93 */
691 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
692 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
693 0x00, 0x00, 0x00, 0x00,
694 },
695 { /* Init_SRA0_SRAF */
696 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
697 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
698 },
699 { /* Init_GR00_GR08 */
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
701 0xFF,
702 },
703 { /* Init_AR00_AR14 */
704 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
705 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
706 0x41, 0x00, 0x0F, 0x00, 0x00,
707 },
708 { /* Init_CR00_CR18 */
709 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
710 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
712 0xFF,
713 },
714 { /* Init_CR30_CR4D */
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
716 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
717 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
718 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
719 },
720 { /* Init_CR90_CRA7 */
721 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
722 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
723 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
724 },
725 },
726
727 { /* mode#8: 320 x 240 32Bpp 60Hz */
728 320, 240, 32, 60,
729 /* Init_MISC */
730 0xEB,
731 { /* Init_SR0_SR4 */
732 0x03, 0x01, 0x0F, 0x03, 0x0E,
733 },
734 { /* Init_SR10_SR24 */
735 0xF3, 0xB6, 0xC0, 0xDD, 0x00, 0x0E, 0x17, 0x2C,
736 0x99, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
737 0xC4, 0x32, 0x02, 0x01, 0x01,
738 },
739 { /* Init_SR30_SR75 */
740 0x38, 0x03, 0x20, 0x09, 0xC0, 0x3A, 0x3A, 0x3A,
741 0x3A, 0x3A, 0x3A, 0x3A, 0x00, 0x00, 0x03, 0xFF,
742 0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
743 0x20, 0x0C, 0x44, 0x20, 0x00, 0x00, 0x00, 0x3A,
744 0x06, 0x68, 0xA7, 0x7F, 0x83, 0x24, 0xFF, 0x03,
745 0x00, 0x60, 0x59, 0x3A, 0x3A, 0x00, 0x00, 0x3A,
746 0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
747 0x50, 0x03, 0x74, 0x14, 0x08, 0x43, 0x08, 0x43,
748 0x04, 0x45, 0x30, 0x30, 0x40, 0x20,
749 },
750 { /* Init_SR80_SR93 */
751 0xFF, 0x07, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x3A,
752 0xF7, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x3A, 0x3A,
753 0x00, 0x00, 0x00, 0x00,
754 },
755 { /* Init_SRA0_SRAF */
756 0x00, 0xFB, 0x9F, 0x01, 0x00, 0xED, 0xED, 0xED,
757 0x7B, 0xFB, 0xFF, 0xFF, 0x97, 0xEF, 0xBF, 0xDF,
758 },
759 { /* Init_GR00_GR08 */
760 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
761 0xFF,
762 },
763 { /* Init_AR00_AR14 */
764 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
765 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
766 0x41, 0x00, 0x0F, 0x00, 0x00,
767 },
768 { /* Init_CR00_CR18 */
769 0xA3, 0x7F, 0x7F, 0x00, 0x85, 0x16, 0x24, 0xF5,
770 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771 0x03, 0x09, 0xFF, 0x80, 0x40, 0xFF, 0x00, 0xE3,
772 0xFF,
773 },
774 { /* Init_CR30_CR4D */
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20,
776 0x00, 0x00, 0x30, 0x40, 0x00, 0xFF, 0xBF, 0xFF,
777 0x2E, 0x27, 0x00, 0x2b, 0x0c, 0x0F, 0xEF, 0x00,
778 0xFe, 0x0f, 0x01, 0xC0, 0x27, 0xEF,
779 },
780 { /* Init_CR90_CRA7 */
781 0x55, 0xD9, 0x5D, 0xE1, 0x86, 0x1B, 0x8E, 0x26,
782 0xDA, 0x8D, 0xDE, 0x94, 0x00, 0x00, 0x18, 0x00,
783 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x15, 0x03,
784 },
785 },
786};
787
788#define numVGAModes ARRAY_SIZE(VGAMode)