use broken-out patches for the coldfire to make it easier to follow differences again...
[openwrt.git] / target / linux / coldfire / patches / 079-m547x_8x_pci_video_sm712.patch
1 From a4c49cdc530046ded7a9fbfe9e13eab10d3973c7 Mon Sep 17 00:00:00 2001
2 From: Kurt Mahan <kmahan@freescale.com>
3 Date: Thu, 10 Jul 2008 19:19:29 -0600
4 Subject: [PATCH] Add PCI Video SM712.
5
6 LTIBName: m547x-8x-pci-video-sm712
7 Signed-off-by: Kurt Mahan <kmahan@freescale.com>
8 Signed-off-by: Shrek Wu <b16972@freescale.com>
9 ---
10  drivers/video/Kconfig           |   10 +
11  drivers/video/Makefile          |    1 +
12  drivers/video/cfbimgblt.c       |    8 +-
13  drivers/video/console/bitblit.c |   12 +
14  drivers/video/console/fbcon.c   |    7 +-
15  drivers/video/smifb.c           |  949 +++++++++++++++++++++++++++++++++++++++
16  drivers/video/smifb.h           |  149 ++++++
17  include/linux/fb.h              |   13 +-
18  8 files changed, 1142 insertions(+), 7 deletions(-)
19  create mode 100644 drivers/video/smifb.c
20  create mode 100644 drivers/video/smifb.h
21
22 --- a/drivers/video/Kconfig
23 +++ b/drivers/video/Kconfig
24 @@ -201,6 +201,16 @@ config FB_TILEBLITTING
25  comment "Frame buffer hardware drivers"
26         depends on FB
27  
28 +config FB_SMI
29 +       tristate "SiliconMotion Lynx support"
30 +       depends on FB && PCI
31 +       select FB_CFB_FILLRECT
32 +       select FB_CFB_COPYAREA
33 +       select FB_CFB_IMAGEBLIT
34 +       ---help---
35 +         This enables support for the Silicon Motion Lynx family of graphic
36 +         chips. It has been tested on ColdFire.
37 +
38  config FB_CIRRUS
39         tristate "Cirrus Logic support"
40         depends on FB && (ZORRO || PCI)
41 --- a/drivers/video/Makefile
42 +++ b/drivers/video/Makefile
43 @@ -28,6 +28,7 @@ obj-$(CONFIG_FB_DDC)           += fb_ddc
44  obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o
45  
46  # Hardware specific drivers go first
47 +obj-$(CONFIG_FB_SMI)              += smifb.o
48  obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
49  obj-$(CONFIG_FB_ARC)              += arcfb.o
50  obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o
51 --- a/drivers/video/cfbimgblt.c
52 +++ b/drivers/video/cfbimgblt.c
53 @@ -44,12 +44,12 @@
54  #endif
55  
56  static const u32 cfb_tab8[] = {
57 -#if defined(__BIG_ENDIAN)
58 +#if defined(__BIG_ENDIAN) && !defined(CONFIG_COLDFIRE)
59      0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
60      0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
61      0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
62      0xffff0000,0xffff00ff,0xffffff00,0xffffffff
63 -#elif defined(__LITTLE_ENDIAN)
64 +#elif defined(__LITTLE_ENDIAN) || defined(CONFIG_COLDFIRE)
65      0x00000000,0xff000000,0x00ff0000,0xffff0000,
66      0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
67      0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
68 @@ -60,9 +60,9 @@ static const u32 cfb_tab8[] = {
69  };
70  
71  static const u32 cfb_tab16[] = {
72 -#if defined(__BIG_ENDIAN)
73 +#if defined(__BIG_ENDIAN) && !defined(CONFIG_COLDFIRE)
74      0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
75 -#elif defined(__LITTLE_ENDIAN)
76 +#elif defined(__LITTLE_ENDIAN) || defined(CONFIG_COLDFIRE)
77      0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
78  #else
79  #error FIXME: No endianness??
80 --- a/drivers/video/console/bitblit.c
81 +++ b/drivers/video/console/bitblit.c
82 @@ -78,7 +78,11 @@ static inline void bit_putcs_aligned(str
83                                      u32 d_pitch, u32 s_pitch, u32 cellsize,
84                                      struct fb_image *image, u8 *buf, u8 *dst)
85  {
86 +#ifndef CONFIG_COLDFIRE
87         u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
88 +#else
89 +        u32 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
90 +#endif
91         u32 idx = vc->vc_font.width >> 3;
92         u8 *src;
93  
94 @@ -111,7 +115,11 @@ static inline void bit_putcs_unaligned(s
95                                        struct fb_image *image, u8 *buf,
96                                        u8 *dst)
97  {
98 +#ifndef CONFIG_COLDFIRE
99         u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
100 +#else
101 +        u32 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
102 +#endif
103         u32 shift_low = 0, mod = vc->vc_font.width % 8;
104         u32 shift_high = 8;
105         u32 idx = vc->vc_font.width >> 3;
106 @@ -238,7 +246,11 @@ static void bit_cursor(struct vc_data *v
107  {
108         struct fb_cursor cursor;
109         struct fbcon_ops *ops = info->fbcon_par;
110 +#ifndef CONFIG_COLDFIRE
111         unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
112 +#else
113 +        unsigned long charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
114 +#endif
115         int w = (vc->vc_font.width + 7) >> 3, c;
116         int y = real_y(ops->p, vc->vc_y);
117         int attribute, use_sw = (vc->vc_cursor_type & 0x10);
118 --- a/drivers/video/console/fbcon.c
119 +++ b/drivers/video/console/fbcon.c
120 @@ -2679,8 +2679,11 @@ static int fbcon_set_palette(struct vc_d
121  {
122         struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
123         int i, j, k, depth;
124 -       u8 val;
125 -
126 +#ifndef CONFIG_COLDFIRE
127 +        u8 val;
128 +#else
129 +        u32 val;
130 +#endif
131         if (fbcon_is_inactive(vc, info))
132                 return -EINVAL;
133  
134 --- /dev/null
135 +++ b/drivers/video/smifb.c
136 @@ -0,0 +1,949 @@
137 +/***************************************************************************
138 +        smifb.c  -  Silicon Motion, Inc. LynxEM+ frame buffer device
139 +                             -------------------
140 +    begin                : Thu Aug 9 2001
141 +    copyright            : (C) 2001 by Szu-Tao Huang
142 +    email                : johuang@siliconmotion.com
143 + ***************************************************************************/
144 +
145 +/***************************************************************************
146 + *                                                                         *
147 + *   This program is free software; you can redistribute it and/or modify  *
148 + *   it under the terms of the GNU General Public License as published by  *
149 + *   the Free Software Foundation; either version 2 of the License, or     *
150 + *   (at your option) any later version.                                   *
151 + *                                                                         *
152 + ***************************************************************************/
153 +
154 +#include <linux/module.h>
155 +#include <linux/kernel.h>
156 +#include <linux/errno.h>
157 +#include <linux/string.h>
158 +#include <linux/mm.h>
159 +#include <linux/tty.h>
160 +#include <linux/slab.h>
161 +#include <linux/delay.h>
162 +#include <linux/fb.h>
163 +#include <linux/pci.h>
164 +#include <linux/init.h>
165 +
166 +#include <asm/io.h>
167 +#include <asm/irq.h>
168 +#include <asm/pgtable.h>
169 +#include <asm/system.h>
170 +#include <asm/uaccess.h>
171 +
172 +#include "console/fbcon.h"
173 +
174 +/*
175 +#include <video/fbcon.h>
176 +#include <video/fbcon-cfb8.h>
177 +#include <video/fbcon-cfb16.h>
178 +#include <video/fbcon-cfb24.h>
179 +*/
180 +
181 +#include <linux/fb.h>
182 +
183 +static char *SMIRegs;          // point to virtual Memory Map IO starting address
184 +static char *SMILFB;           // point to virtual video memory starting address
185 +static struct par_info hw;     // used to record hardware information
186 +
187 +#include "smifb.h"
188 +
189 +struct ModeInit VGAMode[numVGAModes] =
190 +{
191 +       {
192 +               /*  mode#0: 640 x 480  8Bpp  60Hz */
193 +               640, 480, 8, 60,
194 +               /*  Init_MISC */
195 +               0xE3,
196 +               {   /*  Init_SR0_SR4 */
197 +                       0x03, 0x01, 0x0F, 0x00, 0x0E,
198 +               },
199 +               {   /*  Init_SR10_SR24 */
200 +                       0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
201 +                       0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 +                       0xC4, 0x30, 0x02, 0x01, 0x01,
203 +               },
204 +               {   /*  Init_SR30_SR75 */
205 +                       0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
206 +                       0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
207 +                       0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
208 +                       0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
209 +                       0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
210 +                       0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
211 +                       0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
212 +                       0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
213 +                       0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
214 +               },
215 +               {   /*  Init_SR80_SR93 */
216 +                       0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
217 +                       0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
218 +                       0x00, 0x00, 0x00, 0x00,
219 +               },
220 +               {   /*  Init_SRA0_SRAF */
221 +                       0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
222 +                       0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
223 +               },
224 +               {   /*  Init_GR00_GR08 */
225 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
226 +                       0xFF,
227 +               },
228 +               {   /*  Init_AR00_AR14 */
229 +                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
230 +                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
231 +                       0x41, 0x00, 0x0F, 0x00, 0x00,
232 +               },
233 +               {   /*  Init_CR00_CR18 */
234 +                       0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
235 +                       0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 +                       0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
237 +                       0xFF,
238 +               },
239 +               {   /*  Init_CR30_CR4D */
240 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
241 +                       0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
242 +                       0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
243 +                       0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
244 +               },
245 +               {   /*  Init_CR90_CRA7 */
246 +                       0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
247 +                       0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
248 +                       0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
249 +               },
250 +       },
251 +       {
252 +               /*  mode#1: 640 x 480  16Bpp  60Hz */
253 +               640, 480, 16, 60,
254 +               /*  Init_MISC */
255 +               0xE3,
256 +               {   /*  Init_SR0_SR4 */
257 +                       0x03, 0x01, 0x0F, 0x00, 0x0E,
258 +               },
259 +               {   /*  Init_SR10_SR24 */
260 +                       0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
261 +                       0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 +                       0xC4, 0x30, 0x02, 0x01, 0x01,
263 +               },
264 +               {   /*  Init_SR30_SR75 */
265 +                       0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
266 +                       0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
267 +                       0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
268 +                       0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
269 +                       0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
270 +                       0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
271 +                       0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
272 +                       0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
273 +                       0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
274 +               },
275 +               {   /*  Init_SR80_SR93 */
276 +                       0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
277 +                       0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
278 +                       0x00, 0x00, 0x00, 0x00,
279 +               },
280 +               {   /*  Init_SRA0_SRAF */
281 +                       0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
282 +                       0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
283 +               },
284 +               {   /*  Init_GR00_GR08 */
285 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
286 +                       0xFF,
287 +               },
288 +               {   /*  Init_AR00_AR14 */
289 +                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
290 +                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
291 +                       0x41, 0x00, 0x0F, 0x00, 0x00,
292 +               },
293 +               {   /*  Init_CR00_CR18 */
294 +                       0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
295 +                       0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 +                       0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
297 +                       0xFF,
298 +               },
299 +               {   /*  Init_CR30_CR4D */
300 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
301 +                       0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
302 +                       0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
303 +                       0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
304 +               },
305 +               {   /*  Init_CR90_CRA7 */
306 +                       0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
307 +                       0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
308 +                       0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
309 +               },
310 +       },
311 +       {
312 +               /*  mode#2: 640 x 480  24Bpp  60Hz */
313 +               640, 480, 24, 60,
314 +               /*  Init_MISC */
315 +               0xE3,
316 +               {   /*  Init_SR0_SR4 */
317 +                       0x03, 0x01, 0x0F, 0x00, 0x0E,
318 +               },
319 +               {   /*  Init_SR10_SR24 */
320 +                       0xFF, 0xBE, 0xEF, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
321 +                       0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 +                       0xC4, 0x30, 0x02, 0x01, 0x01,
323 +               },
324 +               {   /*  Init_SR30_SR75 */
325 +                       0x32, 0x03, 0xA0, 0x09, 0xC0, 0x32, 0x32, 0x32,
326 +                       0x32, 0x32, 0x32, 0x32, 0x00, 0x00, 0x03, 0xFF,
327 +                       0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
328 +                       0x20, 0x0C, 0x44, 0x20, 0x00, 0x32, 0x32, 0x32,
329 +                       0x04, 0x24, 0x63, 0x4F, 0x52, 0x0B, 0xDF, 0xEA,
330 +                       0x04, 0x50, 0x19, 0x32, 0x32, 0x00, 0x00, 0x32,
331 +                       0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
332 +                       0x50, 0x03, 0x74, 0x14, 0x07, 0x82, 0x07, 0x04,
333 +                       0x00, 0x45, 0x30, 0x30, 0x40, 0x30,
334 +               },
335 +               {   /*  Init_SR80_SR93 */
336 +                       0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x32,
337 +                       0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x32, 0x32,
338 +                       0x00, 0x00, 0x00, 0x00,
339 +               },
340 +               {   /*  Init_SRA0_SRAF */
341 +                       0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
342 +                       0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xFF, 0xDF,
343 +               },
344 +               {   /*  Init_GR00_GR08 */
345 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
346 +                       0xFF,
347 +               },
348 +               {   /*  Init_AR00_AR14 */
349 +                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
350 +                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
351 +                       0x41, 0x00, 0x0F, 0x00, 0x00,
352 +               },
353 +               {   /*  Init_CR00_CR18 */
354 +                       0x5F, 0x4F, 0x4F, 0x00, 0x53, 0x1F, 0x0B, 0x3E,
355 +                       0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 +                       0xEA, 0x0C, 0xDF, 0x50, 0x40, 0xDF, 0x00, 0xE3,
357 +                       0xFF,
358 +               },
359 +               {   /*  Init_CR30_CR4D */
360 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x20,
361 +                       0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xFF, 0xFD,
362 +                       0x5F, 0x4F, 0x00, 0x54, 0x00, 0x0B, 0xDF, 0x00,
363 +                       0xEA, 0x0C, 0x2E, 0x00, 0x4F, 0xDF,
364 +               },
365 +               {   /*  Init_CR90_CRA7 */
366 +                       0x56, 0xDD, 0x5E, 0xEA, 0x87, 0x44, 0x8F, 0x55,
367 +                       0x0A, 0x8F, 0x55, 0x0A, 0x00, 0x00, 0x18, 0x00,
368 +                       0x11, 0x10, 0x0B, 0x0A, 0x0A, 0x0A, 0x0A, 0x00,
369 +               },
370 +       },
371 +       {/*  mode#3: 800 x 600  8Bpp  60Hz */
372 +               800,600,8,60,
373 +               0x2B,   /*  Init_MISC */
374 +               {       /*  Init_SR0_SR4 */
375 +                       0x03, 0x01, 0x0F, 0x03, 0x0E,
376 +               },
377 +               {   /*  Init_SR10_SR24 */
378 +                       0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
379 +                       0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
380 +                       0xC4, 0x30, 0x02, 0x01, 0x01,
381 +               },
382 +               {   /*  Init_SR30_SR75 */
383 +                       0x24, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
384 +                       0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
385 +                       0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
386 +                       0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
387 +                       0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
388 +                       0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
389 +                       0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
390 +                       0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
391 +                       0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
392 +               },
393 +               {   /*  Init_SR80_SR93 */
394 +                       0xFF, 0x87, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
395 +                       0x90, 0x01, 0x2C, 0x01, 0xFF, 0x00, 0x24, 0x24,
396 +                       0x00, 0x00, 0x00, 0x00,
397 +               },
398 +               {   /*  Init_SRA0_SRAF */
399 +                       0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
400 +                       0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
401 +               },
402 +               {   /*  Init_GR00_GR08 */
403 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
404 +                       0xFF,
405 +               },
406 +               {   /*  Init_AR00_AR14 */
407 +                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
408 +                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
409 +                       0x41, 0x00, 0x0F, 0x00, 0x00,
410 +               },
411 +               {   /*  Init_CR00_CR18 */
412 +                       0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
413 +                       0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 +                       0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
415 +                       0xFF,
416 +               },
417 +               {   /*  Init_CR30_CR4D */
418 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
419 +                       0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
420 +                       0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
421 +                       0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
422 +               },
423 +               {   /*  Init_CR90_CRA7 */
424 +                       0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
425 +                       0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
426 +                       0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
427 +               },
428 +       },
429 +       {/*  mode#4: 800 x 600  16Bpp  60Hz */
430 +               800, 600, 16, 60,
431 +               /*  Init_MISC */
432 +               0x2B,
433 +               {   /*  Init_SR0_SR4 */
434 +                       0x03, 0x01, 0x0F, 0x03, 0x0E,
435 +               },
436 +               {   /*  Init_SR10_SR24 */
437 +                       0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
438 +                       0x99, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
439 +                       0xC4, 0x30, 0x02, 0x01, 0x01,
440 +               },
441 +               {   /*  Init_SR30_SR75 */
442 +                       0x24, 0x03, 0x20, 0x09, 0xC0, 0x24, 0x24, 0x24,
443 +                       0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x03, 0xFF,
444 +                       0x00, 0xFC, 0x00, 0x00, 0x20, 0x38, 0x00, 0xFC,
445 +                       0x20, 0x0C, 0x44, 0x20, 0x00, 0x24, 0x24, 0x24,
446 +                       0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
447 +                       0x04, 0x55, 0x59, 0x24, 0x24, 0x00, 0x00, 0x24,
448 +                       0x01, 0x80, 0x7A, 0x1A, 0x1A, 0x00, 0x00, 0x00,
449 +                       0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
450 +                       0x02, 0x45, 0x30, 0x35, 0x40, 0x20,
451 +               },
452 +               {   /*  Init_SR80_SR93 */
453 +                       0x00, 0x00, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x24,
454 +                       0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x24, 0x24,
455 +                       0x00, 0x00, 0x00, 0x00,
456 +               },
457 +               {   /*  Init_SRA0_SRAF */
458 +                       0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
459 +                       0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
460 +               },
461 +               {   /*  Init_GR00_GR08 */
462 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
463 +                       0xFF,
464 +               },
465 +               {   /*  Init_AR00_AR14 */
466 +                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
467 +                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
468 +                       0x41, 0x00, 0x0F, 0x00, 0x00,
469 +               },
470 +               {   /*  Init_CR00_CR18 */
471 +                       0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
472 +                       0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 +                       0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
474 +                       0xFF,
475 +               },
476 +               {   /*  Init_CR30_CR4D */
477 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
478 +                       0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
479 +                       0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
480 +                       0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
481 +               },
482 +               {   /*  Init_CR90_CRA7 */
483 +                       0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
484 +                       0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
485 +                       0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
486 +               },
487 +       },
488 +               {/*  mode#5: 800 x 600  24Bpp  60Hz */
489 +               800,600,24,60,
490 +               0x2B,
491 +               {   /*  Init_SR0_SR4 */
492 +                       0x03, 0x01, 0x0F, 0x03, 0x0E,
493 +               },
494 +               {   /*  Init_SR10_SR24 */
495 +                       0xFF, 0xBE, 0xEE, 0xFF, 0x00, 0x0E, 0x17, 0x2C,
496 +                       0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
497 +                       0xC4, 0x30, 0x02, 0x01, 0x01,
498 +               },
499 +               {   /*  Init_SR30_SR75 */
500 +                       0x36, 0x03, 0x20, 0x09, 0xC0, 0x36, 0x36, 0x36,
501 +                       0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x03, 0xFF,
502 +                       0x00, 0xFC, 0x00, 0x00, 0x20, 0x18, 0x00, 0xFC,
503 +                       0x20, 0x0C, 0x44, 0x20, 0x00, 0x36, 0x36, 0x36,
504 +                       0x04, 0x48, 0x83, 0x63, 0x68, 0x72, 0x57, 0x58,
505 +                       0x04, 0x55, 0x59, 0x36, 0x36, 0x00, 0x00, 0x36,
506 +                       0x01, 0x80, 0x7E, 0x1A, 0x1A, 0x00, 0x00, 0x00,
507 +                       0x50, 0x03, 0x74, 0x14, 0x1C, 0x85, 0x35, 0x13,
508 +                       0x02, 0x45, 0x30, 0x30, 0x40, 0x20,
509 +               },
510 +               {   /*  Init_SR80_SR93 */
511 +                       0xFF, 0x07, 0x00, 0x6F, 0x7F, 0x7F, 0xFF, 0x36,
512 +                       0xF7, 0x00, 0x00, 0x00, 0xEF, 0xFF, 0x36, 0x36,
513 +                       0x00, 0x00, 0x00, 0x00,
514 +               },
515 +               {   /*  Init_SRA0_SRAF */
516 +                       0x00, 0xFF, 0xBF, 0xFF, 0xFF, 0xED, 0xED, 0xED,
517 +                       0x7B, 0xFF, 0xFF, 0xFF, 0xBF, 0xEF, 0xBF, 0xDF,
518 +               },
519 +               {   /*  Init_GR00_GR08 */
520 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
521 +                       0xFF,
522 +               },
523 +               {   /*  Init_AR00_AR14 */
524 +                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
525 +                       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
526 +                       0x41, 0x00, 0x0F, 0x00, 0x00,
527 +               },
528 +               {   /*  Init_CR00_CR18 */
529 +                       0x7F, 0x63, 0x63, 0x00, 0x68, 0x18, 0x72, 0xF0,
530 +                       0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 +                       0x58, 0x0C, 0x57, 0x64, 0x40, 0x57, 0x00, 0xE3,
532 +                       0xFF,
533 +               },
534 +               {   /*  Init_CR30_CR4D */
535 +                       0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x03, 0x20,
536 +                       0x00, 0x00, 0x00, 0x40, 0x00, 0xE7, 0xBF, 0xFD,
537 +                       0x7F, 0x63, 0x00, 0x69, 0x18, 0x72, 0x57, 0x00,
538 +                       0x58, 0x0C, 0xE0, 0x20, 0x63, 0x57,
539 +               },
540 +               {   /*  Init_CR90_CRA7 */
541 +                       0x56, 0x4B, 0x5E, 0x55, 0x86, 0x9D, 0x8E, 0xAA,
542 +                       0xDB, 0x2A, 0xDF, 0x33, 0x00, 0x00, 0x18, 0x00,
543 +                       0x20, 0x1F, 0x1A, 0x19, 0x0F, 0x0F, 0x0F, 0x00,
544 +               },
545 +       },
546 +};
547 +
548 +static void smi_set_timing(struct smifb_info *sfb,struct par_info *hw)
549 +{
550 +       int i=0,j=0;
551 +        u32 m_nScreenStride;
552 +
553 +
554 +    for (j=0;j < numVGAModes;j++) {
555 +               if (VGAMode[j].mmSizeX == hw->width &&
556 +                       VGAMode[j].mmSizeY == hw->height &&
557 +                       VGAMode[j].bpp == sfb->fb.var.bits_per_pixel &&
558 +                       VGAMode[j].hz == hw->hz)
559 +               {
560 +                       
561 +                       smi_mmiowb(0x0,0x3c6);
562 +
563 +                       smi_seqw(0,0x1);
564 +
565 +                       smi_mmiowb(VGAMode[j].Init_MISC,0x3c2);
566 +
567 +                       for (i=0;i<SIZE_SR00_SR04;i++)  // init SEQ register SR00 - SR04
568 +                       {
569 +                               smi_seqw(i,VGAMode[j].Init_SR00_SR04[i]);
570 +                       }
571 +
572 +                       for (i=0;i<SIZE_SR10_SR24;i++)  // init SEQ register SR10 - SR24
573 +                       {
574 +                               smi_seqw(i+0x10,VGAMode[j].Init_SR10_SR24[i]);
575 +                       }
576 +
577 +                       for (i=0;i<SIZE_SR30_SR75;i++)  // init SEQ register SR30 - SR75
578 +                       {
579 +                               if (((i+0x30) != 0x62) && ((i+0x30) != 0x6a) && ((i+0x30) != 0x6b))
580 +                                       smi_seqw(i+0x30,VGAMode[j].Init_SR30_SR75[i]);
581 +                       }
582 +                       for (i=0;i<SIZE_SR80_SR93;i++)  // init SEQ register SR80 - SR93
583 +                       {
584 +                               smi_seqw(i+0x80,VGAMode[j].Init_SR80_SR93[i]);
585 +                       }
586 +                       for (i=0;i<SIZE_SRA0_SRAF;i++)  // init SEQ register SRA0 - SRAF
587 +                       {
588 +                               smi_seqw(i+0xa0,VGAMode[j].Init_SRA0_SRAF[i]);
589 +                       }
590 +
591 +                       for (i=0;i<SIZE_GR00_GR08;i++)  // init Graphic register GR00 - GR08
592 +                       {
593 +                               smi_grphw(i,VGAMode[j].Init_GR00_GR08[i]);
594 +                       }
595 +
596 +                       for (i=0;i<SIZE_AR00_AR14;i++)  // init Attribute register AR00 - AR14
597 +                       {
598 +
599 +                               smi_attrw(i,VGAMode[j].Init_AR00_AR14[i]);
600 +                       }
601 +
602 +                       for (i=0;i<SIZE_CR00_CR18;i++)  // init CRTC register CR00 - CR18
603 +                       {
604 +                               smi_crtcw(i,VGAMode[j].Init_CR00_CR18[i]);
605 +                       }
606 +
607 +                       for (i=0;i<SIZE_CR30_CR4D;i++)  // init CRTC register CR30 - CR4D
608 +                       {
609 +                               smi_crtcw(i+0x30,VGAMode[j].Init_CR30_CR4D[i]);
610 +                       }
611 +
612 +                       for (i=0;i<SIZE_CR90_CRA7;i++)  // init CRTC register CR90 - CRA7
613 +                       {
614 +                               smi_crtcw(i+0x90,VGAMode[j].Init_CR90_CRA7[i]);
615 +                       }
616 +               }
617 +       }
618 +       smi_mmiowb(0x67,0x3c2);
619 +       // set VPR registers
620 +       writel(0x0,hw->m_pVPR+0x0C);
621 +       writel(0x0,hw->m_pVPR+0x40);
622 +       // set data width
623 +       m_nScreenStride = (hw->width * sfb->fb.var.bits_per_pixel) / 64;
624 +       switch (sfb->fb.var.bits_per_pixel)
625 +       {
626 +               case 8:
627 +                       writel(0x0,hw->m_pVPR+0x0);
628 +                       break;
629 +               case 16:
630 +                       writel(0x00020000,hw->m_pVPR+0x0);
631 +                       break;
632 +               case 24:
633 +                       writel(0x00040000,hw->m_pVPR+0x0);
634 +                       break;
635 +       }
636 +       writel((u32)(((m_nScreenStride + 2) << 16) | m_nScreenStride),hw->m_pVPR+0x10);
637 +}
638 +
639 +/*
640 + * Set the color palette
641 + */
642 +static int
643 +smifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
644 +                  u_int trans, struct fb_info *info)
645 +{
646 +       
647 +       struct smifb_info *sfb = (struct smifbinfo *)info;
648 +       u32 *pal;
649 +
650 +       switch (sfb->fb.fix.visual) {
651 +       case FB_VISUAL_TRUECOLOR:               /* RGB 5:6:5 True Colour */
652 +               pal = sfb->fb.pseudo_palette;   // System has 16 default color
653 +               if (regno >= 16)
654 +                       return 1;
655 +
656 +               pal[regno] = (red & 0xf800) |
657 +                   ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
658 +               break;
659 +       }
660 +
661 +       return 0;
662 +}
663 +
664 +/*
665 + *  smifb_decode_var():
666 + *    Get the video params out of 'var'. If a value doesn't fit, round it up,
667 + *    if it's too big, return -EINVAL.
668 + *
669 + *    Suggestion: Round up in the following order: bits_per_pixel, xres,
670 + *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
671 + *    bitfields, horizontal timing, vertical timing.
672 + */
673 +static int smifb_decode_var(struct fb_var_screeninfo *var, struct smifb_info *sfb, struct par_info *hw)
674 +{
675 +    hw->width = var->xres;
676 +    hw->height = var->yres;
677 +    hw->hz = 60;
678 +
679 +       return 0;
680 +}
681 +
682 +static int smifb_set_par (struct fb_info *info)
683 +{
684 +       struct smifb_info *sfb = (struct smifb_info *)info;
685 +       int err, chgvar = 0;
686 +       struct fb_var_screeninfo *var = &info->var;
687 +       struct fb_cmap *cmap;
688 +
689 +
690 +       /*
691 +        * Decode var contents into a par structure, adjusting any
692 +        * out of range values.
693 +        */
694 +       err = smifb_decode_var(var, sfb, &hw);
695 +       if (err) {
696 +               return err;
697 +       }
698 +
699 +       if (hw.width != var->xres)
700 +               chgvar = 1;
701 +       if (hw.height != var->yres)
702 +               chgvar = 1;
703 +
704 +       var->activate           &= ~FB_ACTIVATE_ALL;
705 +
706 +       smi_set_timing(sfb, &hw);
707 +
708 +       sfb->palette_size = var->bits_per_pixel == 8 ? 256 : 16;
709 +       cmap = fb_default_cmap(sfb->palette_size);
710 +       fb_set_cmap(cmap, &sfb->fb);
711 +
712 +       return 0;
713 +}
714 +
715 +static int smifb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
716 +{
717 +       var->bits_per_pixel += 7;
718 +       var->bits_per_pixel &= ~7;
719 +
720 +       var->xres_virtual =
721 +           var->xres_virtual < var->xres ? var->xres : var->xres_virtual;
722 +       var->yres_virtual =
723 +           var->yres_virtual < var->yres ? var->yres : var->yres_virtual;
724 +
725 +       switch (var->bits_per_pixel) {
726 +       case 8:
727 +       case 16:                /* RGB 565 */
728 +    case 24:
729 +               break;
730 +       default:
731 +               return -EINVAL;
732 +       }
733 +
734 +       switch (var->bits_per_pixel) {
735 +       case 16:
736 +               var->red.offset = 11;
737 +               var->red.length = 5;
738 +               var->green.offset       = 5;
739 +               var->green.length       = 6;
740 +               var->blue.offset        = 0;
741 +               var->blue.length        = 5;
742 +
743 +               info->fix.visual                = FB_VISUAL_TRUECOLOR;
744 +               info->fix.line_length= var->xres * 2;
745 +
746 +               break;
747 +       default:
748 +               return -EINVAL; /* We don't support anything other than 16bpp for now. --NL */
749 +               break;
750 +       }
751 +       return 0;
752 +
753 +//     smifb_set_color_bitfields(var);
754 +
755 +    return 0;
756 +}
757 +
758 +/*
759 + * Formal definition of the VESA spec:
760 + *  On
761 + *     This refers to the state of the display when it is in full operation
762 + *  Stand-By
763 + *     This defines an optional operating state of minimal power reduction with
764 + *     the shortest recovery time
765 + *  Suspend
766 + *     This refers to a level of power management in which substantial power
767 + *     reduction is achieved by the display.  The display can have a longer
768 + *     recovery time from this state than from the Stand-by state
769 + *  Off
770 + *     This indicates that the display is consuming the lowest level of power
771 + *     and is non-operational. Recovery from this state may optionally require
772 + *     the user to manually power on the monitor
773 + *
774 + *  Now, the fbdev driver adds an additional state, (blank), where they
775 + *  turn off the video (maybe by colormap tricks), but don't mess with the
776 + *  video itself: think of it semantically between on and Stand-By.
777 + *
778 + *  So here's what we should do in our fbdev blank routine:
779 + *
780 + *     VESA_NO_BLANKING (mode 0)       Video on,  front/back light on
781 + *     VESA_VSYNC_SUSPEND (mode 1)     Video on,  front/back light off
782 + *     VESA_HSYNC_SUSPEND (mode 2)     Video on,  front/back light off
783 + *     VESA_POWERDOWN (mode 3)         Video off, front/back light off
784 + *
785 + *  This will match the matrox implementation.
786 + */
787 +/*
788 + * smifb_blank():
789 + *     Blank the display by setting all palette values to zero.  Note, the
790 + *     12 and 16 bpp modes don't really use the palette, so this will not
791 + *      blank the display in all modes.
792 + */
793 +static int smifb_blank(int blank, struct fb_info *info)
794 +{
795 +//     struct smifb_info *sfb = (struct smifb_info *)info;
796 +#if 0
797 +       switch (blank) {
798 +       case VESA_POWERDOWN:
799 +       case VESA_VSYNC_SUSPEND:
800 +       case VESA_HSYNC_SUSPEND:
801 +       case VESA_NO_BLANKING:
802 +       }
803 +#endif
804 +       return 1;
805 +}
806 +
807 +static struct fb_ops smifb_ops = {
808 +       .owner          = THIS_MODULE,
809 +       .fb_check_var   = smifb_check_var,
810 +       .fb_set_par     = smifb_set_par,
811 +       .fb_setcolreg   = smifb_setcolreg,
812 +       .fb_blank       = smifb_blank,
813 +       
814 +       /* Accelerated functions, using softversions, per se */
815 +       .fb_fillrect    = cfb_fillrect,
816 +       .fb_copyarea    = cfb_copyarea,
817 +       .fb_imageblit   = cfb_imageblit,
818 +       .fb_cursor      = soft_cursor,
819 +};
820 +
821 +/*
822 + * Alloc struct smifb_info and assign the default value
823 + */
824 +static struct smifb_info * __devinit
825 +smi_alloc_fb_info(struct pci_dev *dev, char *name)
826 +{
827 +    struct smifb_info *sfb;
828 +
829 +    sfb = kmalloc(sizeof(struct smifb_info) + sizeof(u32) * 16, GFP_KERNEL);
830 +
831 +    if (!sfb)
832 +        return NULL;
833 +
834 +    memset(sfb, 0, sizeof(struct smifb_info));
835 +
836 +    sfb->currcon        = -1;
837 +    sfb->dev            = dev;
838 +
839 +    strcpy(sfb->fb.fix.id, name);
840 +
841 +    sfb->fb.fix.type           = FB_TYPE_PACKED_PIXELS;
842 +    sfb->fb.fix.type_aux       = 0;
843 +    sfb->fb.fix.xpanstep       = 0;
844 +    sfb->fb.fix.ypanstep       = 0;
845 +    sfb->fb.fix.ywrapstep      = 0;
846 +    sfb->fb.fix.accel          = FB_ACCEL_NONE;
847 +
848 +    sfb->fb.var.nonstd         = 0;
849 +    sfb->fb.var.activate       = FB_ACTIVATE_NOW;
850 +    sfb->fb.var.height         = -1;
851 +    sfb->fb.var.width          = -1;
852 +    sfb->fb.var.accel_flags    = 0;
853 +    sfb->fb.var.vmode          = FB_VMODE_NONINTERLACED;
854 +
855 +    sfb->fb.fbops              = &smifb_ops;
856 +    sfb->fb.flags              = FBINFO_FLAG_DEFAULT;
857 +    sfb->fb.node               = -1;
858 +    sfb->fb.pseudo_palette     = (void *)(&sfb->palette_size + 1);
859 +
860 +    return sfb;
861 +}
862 +
863 +/*
864 + * Unmap in the memory mapped IO registers
865 + *
866 + */
867 +
868 +static void __devinit
869 +smi_unmap_mmio(struct smifb_info *sfb)
870 +{
871 +    if (sfb && SMILFB)
872 +    {
873 +        iounmap(SMILFB);
874 +        SMIRegs = NULL;
875 +    }
876 +}
877 +
878 +/*
879 + * Map in the screen memory
880 + *
881 + */
882 +static int __devinit
883 +smi_map_smem(struct smifb_info *sfb, struct pci_dev *dev, u_long smem_len)
884 +{
885 +
886 +    sfb->fb.fix.smem_start = pci_resource_start(dev, 0);
887 +    sfb->fb.fix.smem_len  = smem_len;
888 +    printk("%s:smem %x,len %x\n",sfb->fb.fix.smem_start,sfb->fb.fix.smem_len);
889 +    sfb->fb.screen_base = SMILFB;
890 +
891 +    if (!sfb->fb.screen_base)
892 +    {
893 +        printk("%s: unable to map screen memory\n",sfb->fb.fix.id);
894 +        return -ENOMEM;
895 +    }
896 +
897 +    return 0;
898 +}
899 +
900 +
901 +/*
902 + * Unmap in the screen memory
903 + *
904 + */
905 +static void __devinit
906 +smi_unmap_smem(struct smifb_info *sfb)
907 +{
908 +    if (sfb && sfb->fb.screen_base)
909 +    {
910 +        iounmap(sfb->fb.screen_base);
911 +        sfb->fb.screen_base = NULL;
912 +    }
913 +}
914 +
915 +/*
916 + * We need to wake up the LynxEM+, and make sure its in linear memory mode.
917 + */
918 +static inline void __devinit
919 +smi_init_hw(void)
920 +{
921 +       /* The delays prevent the ColdFire PCI host from locking up. :/ --NL */
922 +       udelay(1000);
923 +    outb(0x18, 0x3c4);
924 +       udelay(1000);
925 +    outb(0x11, 0x3c5);
926 +       udelay(1000);
927 +       printk("%s: 0x3c4 =%x 0x3c5 %x\n",__FUNCTION__,inw(0x3c4),inw(0x3c5));
928 +}
929 +
930 +static void __devinit
931 +smi_free_fb_info(struct smifb_info *sfb)
932 +{
933 +       if (sfb) {
934 +               fb_alloc_cmap(&sfb->fb.cmap, 0, 0);
935 +               kfree(sfb);
936 +       }
937 +}
938 +
939 +
940 +u16 SMI_ChipIDs[numChipIDs] = {0x710, 0x712, 0x720};
941 +
942 +int __init smifb_init(struct pci_dev *pdev, const struct pci_device_id *ent)
943 +{
944 +    struct smifb_info *sfb;
945 +    u_long smem_size;
946 +    char name[16];
947 +    int err;
948 +       char *m_pLAW;
949 +       ulong m_pLAWPhysical;
950 +
951 +    printk("%s start\n",__FUNCTION__);
952 +    sprintf(name, "smifb");
953 +
954 +    hw.chipID = pdev->device;
955 +    
956 +    err = -ENOMEM;
957 +    sfb = smi_alloc_fb_info(pdev, name);
958 +    if (!sfb) {
959 +        goto failed;
960 +    }
961 +
962 +    smi_init_hw();
963 +
964 +       // Map address and memory detection
965 +       m_pLAWPhysical = pci_resource_start(pdev,0);
966 +       printk("%s:m_pLAWPhysical %x,hw.chipID %x\n",__FUNCTION__,m_pLAWPhysical,hw.chipID);
967 +       switch (hw.chipID) {
968 +               case 0x710:
969 +               case 0x712:
970 +                       sfb->fb.fix.mmio_start = m_pLAWPhysical + 0x00700000;
971 +                       sfb->fb.fix.mmio_len   = 0x00100000;
972 +
973 +               hw.m_pLFB = SMILFB = ioremap(m_pLAWPhysical, 0x00800000);
974 +               printk("%s:SMILFB%x\n",__FUNCTION__,SMILFB);
975 +               hw.m_pMMIO = SMIRegs = SMILFB + 0x00700000;
976 +                       hw.m_pDPR = hw.m_pLFB + 0x00408000;
977 +                       hw.m_pVPR = hw.m_pLFB + 0x0040c000;
978 +
979 +               if (!SMIRegs)
980 +               {
981 +                       printk("%s: unable to map memory mapped IO\n",sfb->fb.fix.id);
982 +                       return -ENOMEM;
983 +               }
984 +
985 +                       smi_seqw(0x62,0x7A);
986 +               smi_seqw(0x6a,0x0c);
987 +               smi_seqw(0x6b,0x02);
988 +               smem_size = 0x00400000;
989 +
990 +               //LynxEM+ memory dection
991 +               *(u32 *)(SMILFB + 4) = 0xAA551133;
992 +               if (*(u32 *)(SMILFB + 4) != 0xAA551133)
993 +               {
994 +                       smem_size = 0x00200000;
995 +                       // Program the MCLK to 130 MHz
996 +                       smi_seqw(0x6a,0x12);
997 +                       smi_seqw(0x6b,0x02);
998 +                       smi_seqw(0x62,0x3e);
999 +               }
1000 +                       break;
1001 +               case 0x720:
1002 +                       sfb->fb.fix.mmio_start = m_pLAWPhysical + 0x000c0000;
1003 +                       sfb->fb.fix.mmio_len   = 0x00040000;
1004 +
1005 +                       m_pLAW = ioremap(m_pLAWPhysical, 0x00a00000);
1006 +                       hw.m_pLFB = SMILFB = m_pLAW + 0x00200000;
1007 +                       hw.m_pMMIO = SMIRegs = m_pLAW + 0x000c0000;
1008 +                       hw.m_pDPR = m_pLAW;
1009 +                       hw.m_pVPR = m_pLAW + 0x800;
1010 +
1011 +                       smi_seqw(0x62,0xff);
1012 +                       smi_seqw(0x6a,0x0d);
1013 +                       smi_seqw(0x6b,0x02);
1014 +                       smem_size = 0x00400000;
1015 +
1016 +                       break;
1017 +       }
1018 +
1019 +       sfb->fb.var.xres = 640;
1020 +       sfb->fb.var.yres = 480;
1021 +       sfb->fb.var.bits_per_pixel = 16;
1022 +
1023 +       sfb->fb.var.xres_virtual = sfb->fb.var.xres;
1024 +
1025 +       sfb->fb.var.yres_virtual = sfb->fb.var.yres;
1026 +       
1027 +       sfb->fb.flags = FBINFO_FLAG_DEFAULT;
1028 +
1029 +       printk("%s:smem_size %x\n",__FUNCTION__,smem_size);
1030 +    err = smi_map_smem(sfb, pdev, smem_size);
1031 +       printk("%s:smi_map_smem error %x\n",__FUNCTION__,err);
1032 +    if (err) {
1033 +               goto failed;
1034 +    }
1035 +
1036 +
1037 +
1038 +       fb_set_var(&sfb->fb, &sfb->fb.var);
1039 +       smifb_check_var(&sfb->fb.var, &sfb->fb);
1040 +       smifb_set_par(sfb);
1041 +       printk("%s:register_framebuffer \n",__FUNCTION__);
1042 +       err = register_framebuffer(&sfb->fb);
1043 +       if (err < 0) {
1044 +               goto failed;
1045 +    }
1046 +
1047 +       printk("Silicon Motion, Inc. LynxEM+ Init complete.\n");
1048 +
1049 +       return 0;
1050 +
1051 +failed:
1052 +       smi_unmap_smem(sfb);
1053 +       smi_unmap_mmio(sfb);
1054 +       smi_free_fb_info(sfb);
1055 +       printk("Silicon Motion, Inc. LynxEM+ Init FAILED.n");
1056 +
1057 +       return err;
1058 +}
1059 +
1060 +struct pci_device_id smifb_pci_tbl[] = {
1061 +        { 0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID },
1062 +        { 0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID },
1063 +        { 0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID },
1064 +        { 0 }
1065 +};
1066 +
1067 +MODULE_DEVICE_TABLE(pci, smifb_pci_tbl);
1068 +
1069 +struct pci_driver smifb_driver = {
1070 +        .name =         "smifb",
1071 +        .id_table =     smifb_pci_tbl,
1072 +        .probe =        smifb_init,
1073 +};
1074 +
1075 +int __init smi_init(void)
1076 +{
1077 +       /*return pci_module_init(&smifb_driver);*/
1078 +       return pci_register_driver(&smifb_driver);
1079 +}
1080 +
1081 +module_init(smi_init);
1082 +MODULE_LICENSE("GPL");
1083 +
1084 +
1085 +
1086 --- /dev/null
1087 +++ b/drivers/video/smifb.h
1088 @@ -0,0 +1,149 @@
1089 +/***************************************************************************
1090 +                       smifb.h  -  SiliconMotion LynxEM+ frame buffer device
1091 +                             -------------------
1092 +    begin                : Thu Aug 9 2001
1093 +    copyright            : (C) 2001 by Szu-Tao Huang
1094 +    email                : johuang@siliconmotion.com
1095 + ***************************************************************************/
1096 +
1097 +/***************************************************************************
1098 + *                                                                         *
1099 + *   This program is free software; you can redistribute it and/or modify  *
1100 + *   it under the terms of the GNU General Public License as published by  *
1101 + *   the Free Software Foundation; either version 2 of the License, or     *
1102 + *   (at your option) any later version.                                   *
1103 + *                                                                         *
1104 + ***************************************************************************/
1105 +
1106 +#define smi_mmiowb(dat,reg)    writeb(dat, SMIRegs + reg)
1107 +#define smi_mmioww(dat,reg)    writew(dat, SMIRegs + reg)
1108 +#define smi_mmiowl(dat,reg)    writel(dat, SMIRegs + reg)
1109 +
1110 +#define smi_mmiorb(reg)                readb(SMIRegs + reg)
1111 +#define smi_mmiorw(reg)                readw(SMIRegs + reg)
1112 +#define smi_mmiorl(reg)                readl(SMIRegs + reg)
1113 +
1114 +#define SIZE_SR00_SR04      (0x04 - 0x00 + 1)
1115 +#define SIZE_SR10_SR24      (0x24 - 0x10 + 1)
1116 +#define SIZE_SR30_SR75      (0x75 - 0x30 + 1)
1117 +#define SIZE_SR80_SR93      (0x93 - 0x80 + 1)
1118 +#define SIZE_SRA0_SRAF      (0xAF - 0xA0 + 1)
1119 +#define SIZE_GR00_GR08      (0x08 - 0x00 + 1)
1120 +#define SIZE_AR00_AR14      (0x14 - 0x00 + 1)
1121 +#define SIZE_CR00_CR18      (0x18 - 0x00 + 1)
1122 +#define SIZE_CR30_CR4D      (0x4D - 0x30 + 1)
1123 +#define SIZE_CR90_CRA7      (0xA7 - 0x90 + 1)
1124 +#define SIZE_VPR                        (0x6C + 1)
1125 +#define SIZE_DPR                       (0x44 + 1)
1126 +
1127 +#define numVGAModes                    6
1128 +#define numChipIDs                     3
1129 +
1130 +#define NR_PALETTE     256
1131 +#define NR_RGB          2
1132 +
1133 +/*
1134 + * Minimum X and Y resolutions
1135 + */
1136 +#define MIN_XRES       640
1137 +#define MIN_YRES       480
1138 +
1139 +static inline void smi_crtcw(int reg, int val)
1140 +{
1141 +        smi_mmiowb(reg, 0x3d4);
1142 +        smi_mmiowb(val, 0x3d5);
1143 +}
1144 +
1145 +static inline unsigned int smi_crtcr(int reg)
1146 +{
1147 +        smi_mmiowb(reg, 0x3d4);
1148 +        return smi_mmiorb(0x3d5);
1149 +}
1150 +
1151 +static inline void smi_grphw(int reg, int val)
1152 +{
1153 +        smi_mmiowb(reg, 0x3ce);
1154 +        smi_mmiowb(val, 0x3cf);
1155 +}
1156 +
1157 +static inline unsigned int smi_grphr(int reg)
1158 +{
1159 +        smi_mmiowb(reg, 0x3ce);
1160 +        return smi_mmiorb(0x3cf);
1161 +}
1162 +
1163 +static inline void smi_attrw(int reg, int val)
1164 +{
1165 +        smi_mmiorb(0x3da);
1166 +        smi_mmiowb(reg, 0x3c0);
1167 +        smi_mmiorb(0x3c1);
1168 +        smi_mmiowb(val, 0x3c0);
1169 +}
1170 +
1171 +static inline void smi_seqw(int reg, int val)
1172 +{
1173 +        smi_mmiowb(reg, 0x3c4);
1174 +        smi_mmiowb(val, 0x3c5);
1175 +}
1176 +
1177 +static inline unsigned int smi_seqr(int reg)
1178 +{
1179 +        smi_mmiowb(reg, 0x3c4);
1180 +        return smi_mmiorb(0x3c5);
1181 +}
1182 +/*
1183 +* Private structure
1184 +*/
1185 +struct smifb_info {
1186 +        /*
1187 +        * The following is a pointer to be passed into the
1188 +        * functions below.  The modules outside the main
1189 +        * smifb.c driver have no knowledge as to what
1190 +        * is within this structure.
1191 +        */
1192 +        struct fb_info          fb;
1193 +        struct display_switch   *dispsw;
1194 +        struct pci_dev         *dev;
1195 +        signed int              currcon;
1196 +
1197 +        struct {
1198 +                u8 red, green, blue;
1199 +        } palette[NR_RGB];
1200 +
1201 +        u_int                   palette_size;
1202 +};
1203 +
1204 +struct par_info {
1205 +       /*
1206 +        * Hardware
1207 +        */
1208 +       u16             chipID;
1209 +       char    *m_pLFB;
1210 +       char    *m_pMMIO;
1211 +       char    *m_pDPR;
1212 +       char    *m_pVPR;
1213 +
1214 +       u_int   width;
1215 +       u_int   height;
1216 +       u_int   hz;
1217 +};
1218 +
1219 +// The next structure holds all information relevant for a specific video mode.
1220 +struct ModeInit
1221 +{
1222 +       int                       mmSizeX;
1223 +       int                       mmSizeY;
1224 +       int                       bpp;
1225 +       int                       hz;
1226 +       unsigned char Init_MISC;
1227 +       unsigned char Init_SR00_SR04[SIZE_SR00_SR04];
1228 +       unsigned char Init_SR10_SR24[SIZE_SR10_SR24];
1229 +       unsigned char Init_SR30_SR75[SIZE_SR30_SR75];
1230 +       unsigned char Init_SR80_SR93[SIZE_SR80_SR93];
1231 +       unsigned char Init_SRA0_SRAF[SIZE_SRA0_SRAF];
1232 +       unsigned char Init_GR00_GR08[SIZE_GR00_GR08];
1233 +       unsigned char Init_AR00_AR14[SIZE_AR00_AR14];
1234 +       unsigned char Init_CR00_CR18[SIZE_CR00_CR18];
1235 +       unsigned char Init_CR30_CR4D[SIZE_CR30_CR4D];
1236 +       unsigned char Init_CR90_CRA7[SIZE_CR90_CRA7];
1237 +};
1238 --- a/include/linux/fb.h
1239 +++ b/include/linux/fb.h
1240 @@ -873,6 +873,17 @@ struct fb_info {
1241  #define fb_writeq sbus_writeq
1242  #define fb_memset sbus_memset_io
1243  
1244 +#elif defined(CONFIG_COLDFIRE)
1245 +#define fb_readb readb
1246 +#define fb_readw readw
1247 +#define fb_readl readl
1248 +#define fb_readq readq
1249 +#define fb_writeb writeb
1250 +#define fb_writew writew
1251 +#define fb_writel writel
1252 +#define fb_writeq writeq
1253 +#define fb_memset memset_io
1254 +
1255  #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || (defined(__sh__) && !defined(__SH5__)) || defined(__powerpc__) || defined(__avr32__)
1256  
1257  #define fb_readb __raw_readb
1258 @@ -899,7 +910,7 @@ struct fb_info {
1259  
1260  #endif
1261  
1262 -#if defined (__BIG_ENDIAN)
1263 +#if defined (__BIG_ENDIAN) && !defined(CONFIG_COLDFIRE)
1264  #define FB_LEFT_POS(bpp)          (32 - bpp)
1265  #define FB_SHIFT_HIGH(val, bits)  ((val) >> (bits))
1266  #define FB_SHIFT_LOW(val, bits)   ((val) << (bits))