Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
savagefb_driver.c
Go to the documentation of this file.
1 /*
2  * linux/drivers/video/savagefb.c -- S3 Savage Framebuffer Driver
3  *
4  * Copyright (c) 2001-2002 Denis Oliver Kropp <[email protected]>
5  * Sven Neumann <[email protected]>
6  *
7  *
8  * Card specific code is based on XFree86's savage driver.
9  * Framebuffer framework code is based on code of cyber2000fb and tdfxfb.
10  *
11  * This file is subject to the terms and conditions of the GNU General
12  * Public License. See the file COPYING in the main directory of this
13  * archive for more details.
14  *
15  * 0.4.0 (neo)
16  * - hardware accelerated clear and move
17  *
18  * 0.3.2 (dok)
19  * - wait for vertical retrace before writing to cr67
20  * at the beginning of savagefb_set_par
21  * - use synchronization registers cr23 and cr26
22  *
23  * 0.3.1 (dok)
24  * - reset 3D engine
25  * - don't return alpha bits for 32bit format
26  *
27  * 0.3.0 (dok)
28  * - added WaitIdle functions for all Savage types
29  * - do WaitIdle before mode switching
30  * - code cleanup
31  *
32  * 0.2.0 (dok)
33  * - first working version
34  *
35  *
36  * TODO
37  * - clock validations in decode_var
38  *
39  * BUGS
40  * - white margin on bootup
41  *
42  */
43 
44 #include <linux/module.h>
45 #include <linux/kernel.h>
46 #include <linux/errno.h>
47 #include <linux/string.h>
48 #include <linux/mm.h>
49 #include <linux/slab.h>
50 #include <linux/delay.h>
51 #include <linux/fb.h>
52 #include <linux/pci.h>
53 #include <linux/init.h>
54 #include <linux/console.h>
55 
56 #include <asm/io.h>
57 #include <asm/irq.h>
58 #include <asm/pgtable.h>
59 
60 #ifdef CONFIG_MTRR
61 #include <asm/mtrr.h>
62 #endif
63 
64 #include "savagefb.h"
65 
66 
67 #define SAVAGEFB_VERSION "0.4.0_2.6"
68 
69 /* --------------------------------------------------------------------- */
70 
71 
72 static char *mode_option __devinitdata = NULL;
73 
74 #ifdef MODULE
75 
76 MODULE_AUTHOR("(c) 2001-2002 Denis Oliver Kropp <[email protected]>");
77 MODULE_LICENSE("GPL");
78 MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips");
79 
80 #endif
81 
82 
83 /* --------------------------------------------------------------------- */
84 
85 static void vgaHWSeqReset(struct savagefb_par *par, int start)
86 {
87  if (start)
88  VGAwSEQ(0x00, 0x01, par); /* Synchronous Reset */
89  else
90  VGAwSEQ(0x00, 0x03, par); /* End Reset */
91 }
92 
93 static void vgaHWProtect(struct savagefb_par *par, int on)
94 {
95  unsigned char tmp;
96 
97  if (on) {
98  /*
99  * Turn off screen and disable sequencer.
100  */
101  tmp = VGArSEQ(0x01, par);
102 
103  vgaHWSeqReset(par, 1); /* start synchronous reset */
104  VGAwSEQ(0x01, tmp | 0x20, par);/* disable the display */
105 
106  VGAenablePalette(par);
107  } else {
108  /*
109  * Reenable sequencer, then turn on screen.
110  */
111 
112  tmp = VGArSEQ(0x01, par);
113 
114  VGAwSEQ(0x01, tmp & ~0x20, par);/* reenable display */
115  vgaHWSeqReset(par, 0); /* clear synchronous reset */
116 
117  VGAdisablePalette(par);
118  }
119 }
120 
121 static void vgaHWRestore(struct savagefb_par *par, struct savage_reg *reg)
122 {
123  int i;
124 
125  VGAwMISC(reg->MiscOutReg, par);
126 
127  for (i = 1; i < 5; i++)
128  VGAwSEQ(i, reg->Sequencer[i], par);
129 
130  /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or
131  CRTC[17] */
132  VGAwCR(17, reg->CRTC[17] & ~0x80, par);
133 
134  for (i = 0; i < 25; i++)
135  VGAwCR(i, reg->CRTC[i], par);
136 
137  for (i = 0; i < 9; i++)
138  VGAwGR(i, reg->Graphics[i], par);
139 
140  VGAenablePalette(par);
141 
142  for (i = 0; i < 21; i++)
143  VGAwATTR(i, reg->Attribute[i], par);
144 
145  VGAdisablePalette(par);
146 }
147 
148 static void vgaHWInit(struct fb_var_screeninfo *var,
149  struct savagefb_par *par,
150  struct xtimings *timings,
151  struct savage_reg *reg)
152 {
153  reg->MiscOutReg = 0x23;
154 
155  if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT))
156  reg->MiscOutReg |= 0x40;
157 
158  if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT))
159  reg->MiscOutReg |= 0x80;
160 
161  /*
162  * Time Sequencer
163  */
164  reg->Sequencer[0x00] = 0x00;
165  reg->Sequencer[0x01] = 0x01;
166  reg->Sequencer[0x02] = 0x0F;
167  reg->Sequencer[0x03] = 0x00; /* Font select */
168  reg->Sequencer[0x04] = 0x0E; /* Misc */
169 
170  /*
171  * CRTC Controller
172  */
173  reg->CRTC[0x00] = (timings->HTotal >> 3) - 5;
174  reg->CRTC[0x01] = (timings->HDisplay >> 3) - 1;
175  reg->CRTC[0x02] = (timings->HSyncStart >> 3) - 1;
176  reg->CRTC[0x03] = (((timings->HSyncEnd >> 3) - 1) & 0x1f) | 0x80;
177  reg->CRTC[0x04] = (timings->HSyncStart >> 3);
178  reg->CRTC[0x05] = ((((timings->HSyncEnd >> 3) - 1) & 0x20) << 2) |
179  (((timings->HSyncEnd >> 3)) & 0x1f);
180  reg->CRTC[0x06] = (timings->VTotal - 2) & 0xFF;
181  reg->CRTC[0x07] = (((timings->VTotal - 2) & 0x100) >> 8) |
182  (((timings->VDisplay - 1) & 0x100) >> 7) |
183  ((timings->VSyncStart & 0x100) >> 6) |
184  (((timings->VSyncStart - 1) & 0x100) >> 5) |
185  0x10 |
186  (((timings->VTotal - 2) & 0x200) >> 4) |
187  (((timings->VDisplay - 1) & 0x200) >> 3) |
188  ((timings->VSyncStart & 0x200) >> 2);
189  reg->CRTC[0x08] = 0x00;
190  reg->CRTC[0x09] = (((timings->VSyncStart - 1) & 0x200) >> 4) | 0x40;
191 
192  if (timings->dblscan)
193  reg->CRTC[0x09] |= 0x80;
194 
195  reg->CRTC[0x0a] = 0x00;
196  reg->CRTC[0x0b] = 0x00;
197  reg->CRTC[0x0c] = 0x00;
198  reg->CRTC[0x0d] = 0x00;
199  reg->CRTC[0x0e] = 0x00;
200  reg->CRTC[0x0f] = 0x00;
201  reg->CRTC[0x10] = timings->VSyncStart & 0xff;
202  reg->CRTC[0x11] = (timings->VSyncEnd & 0x0f) | 0x20;
203  reg->CRTC[0x12] = (timings->VDisplay - 1) & 0xff;
204  reg->CRTC[0x13] = var->xres_virtual >> 4;
205  reg->CRTC[0x14] = 0x00;
206  reg->CRTC[0x15] = (timings->VSyncStart - 1) & 0xff;
207  reg->CRTC[0x16] = (timings->VSyncEnd - 1) & 0xff;
208  reg->CRTC[0x17] = 0xc3;
209  reg->CRTC[0x18] = 0xff;
210 
211  /*
212  * are these unnecessary?
213  * vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN|KGA_ENABLE_ON_ZERO);
214  * vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN|KGA_ENABLE_ON_ZERO);
215  */
216 
217  /*
218  * Graphics Display Controller
219  */
220  reg->Graphics[0x00] = 0x00;
221  reg->Graphics[0x01] = 0x00;
222  reg->Graphics[0x02] = 0x00;
223  reg->Graphics[0x03] = 0x00;
224  reg->Graphics[0x04] = 0x00;
225  reg->Graphics[0x05] = 0x40;
226  reg->Graphics[0x06] = 0x05; /* only map 64k VGA memory !!!! */
227  reg->Graphics[0x07] = 0x0F;
228  reg->Graphics[0x08] = 0xFF;
229 
230 
231  reg->Attribute[0x00] = 0x00; /* standard colormap translation */
232  reg->Attribute[0x01] = 0x01;
233  reg->Attribute[0x02] = 0x02;
234  reg->Attribute[0x03] = 0x03;
235  reg->Attribute[0x04] = 0x04;
236  reg->Attribute[0x05] = 0x05;
237  reg->Attribute[0x06] = 0x06;
238  reg->Attribute[0x07] = 0x07;
239  reg->Attribute[0x08] = 0x08;
240  reg->Attribute[0x09] = 0x09;
241  reg->Attribute[0x0a] = 0x0A;
242  reg->Attribute[0x0b] = 0x0B;
243  reg->Attribute[0x0c] = 0x0C;
244  reg->Attribute[0x0d] = 0x0D;
245  reg->Attribute[0x0e] = 0x0E;
246  reg->Attribute[0x0f] = 0x0F;
247  reg->Attribute[0x10] = 0x41;
248  reg->Attribute[0x11] = 0xFF;
249  reg->Attribute[0x12] = 0x0F;
250  reg->Attribute[0x13] = 0x00;
251  reg->Attribute[0x14] = 0x00;
252 }
253 
254 /* -------------------- Hardware specific routines ------------------------- */
255 
256 /*
257  * Hardware Acceleration for SavageFB
258  */
259 
260 /* Wait for fifo space */
261 static void
262 savage3D_waitfifo(struct savagefb_par *par, int space)
263 {
264  int slots = MAXFIFO - space;
265 
266  while ((savage_in32(0x48C00, par) & 0x0000ffff) > slots);
267 }
268 
269 static void
270 savage4_waitfifo(struct savagefb_par *par, int space)
271 {
272  int slots = MAXFIFO - space;
273 
274  while ((savage_in32(0x48C60, par) & 0x001fffff) > slots);
275 }
276 
277 static void
278 savage2000_waitfifo(struct savagefb_par *par, int space)
279 {
280  int slots = MAXFIFO - space;
281 
282  while ((savage_in32(0x48C60, par) & 0x0000ffff) > slots);
283 }
284 
285 /* Wait for idle accelerator */
286 static void
287 savage3D_waitidle(struct savagefb_par *par)
288 {
289  while ((savage_in32(0x48C00, par) & 0x0008ffff) != 0x80000);
290 }
291 
292 static void
293 savage4_waitidle(struct savagefb_par *par)
294 {
295  while ((savage_in32(0x48C60, par) & 0x00a00000) != 0x00a00000);
296 }
297 
298 static void
299 savage2000_waitidle(struct savagefb_par *par)
300 {
301  while ((savage_in32(0x48C60, par) & 0x009fffff));
302 }
303 
304 #ifdef CONFIG_FB_SAVAGE_ACCEL
305 static void
306 SavageSetup2DEngine(struct savagefb_par *par)
307 {
308  unsigned long GlobalBitmapDescriptor;
309 
310  GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE;
311  BCI_BD_SET_BPP(GlobalBitmapDescriptor, par->depth);
312  BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, par->vwidth);
313 
314  switch(par->chip) {
315  case S3_SAVAGE3D:
316  case S3_SAVAGE_MX:
317  /* Disable BCI */
318  savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
319  /* Setup BCI command overflow buffer */
320  savage_out32(0x48C14,
321  (par->cob_offset >> 11) | (par->cob_index << 29),
322  par);
323  /* Program shadow status update. */
324  savage_out32(0x48C10, 0x78207220, par);
325  savage_out32(0x48C0C, 0, par);
326  /* Enable BCI and command overflow buffer */
327  savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par);
328  break;
329  case S3_SAVAGE4:
330  case S3_TWISTER:
331  case S3_PROSAVAGE:
332  case S3_PROSAVAGEDDR:
333  case S3_SUPERSAVAGE:
334  /* Disable BCI */
335  savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
336  /* Program shadow status update */
337  savage_out32(0x48C10, 0x00700040, par);
338  savage_out32(0x48C0C, 0, par);
339  /* Enable BCI without the COB */
340  savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x08, par);
341  break;
342  case S3_SAVAGE2000:
343  /* Disable BCI */
344  savage_out32(0x48C18, 0, par);
345  /* Setup BCI command overflow buffer */
346  savage_out32(0x48C18,
347  (par->cob_offset >> 7) | (par->cob_index),
348  par);
349  /* Disable shadow status update */
350  savage_out32(0x48A30, 0, par);
351  /* Enable BCI and command overflow buffer */
352  savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x00280000,
353  par);
354  break;
355  default:
356  break;
357  }
358  /* Turn on 16-bit register access. */
359  vga_out8(0x3d4, 0x31, par);
360  vga_out8(0x3d5, 0x0c, par);
361 
362  /* Set stride to use GBD. */
363  vga_out8(0x3d4, 0x50, par);
364  vga_out8(0x3d5, vga_in8(0x3d5, par) | 0xC1, par);
365 
366  /* Enable 2D engine. */
367  vga_out8(0x3d4, 0x40, par);
368  vga_out8(0x3d5, 0x01, par);
369 
370  savage_out32(MONO_PAT_0, ~0, par);
371  savage_out32(MONO_PAT_1, ~0, par);
372 
373  /* Setup plane masks */
374  savage_out32(0x8128, ~0, par); /* enable all write planes */
375  savage_out32(0x812C, ~0, par); /* enable all read planes */
376  savage_out16(0x8134, 0x27, par);
377  savage_out16(0x8136, 0x07, par);
378 
379  /* Now set the GBD */
380  par->bci_ptr = 0;
381  par->SavageWaitFifo(par, 4);
382 
383  BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1);
384  BCI_SEND(0);
385  BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2);
386  BCI_SEND(GlobalBitmapDescriptor);
387 
388  /*
389  * I don't know why, sending this twice fixes the initial black screen,
390  * prevents X from crashing at least in Toshiba laptops with SavageIX.
391  * --Tony
392  */
393  par->bci_ptr = 0;
394  par->SavageWaitFifo(par, 4);
395 
396  BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1);
397  BCI_SEND(0);
398  BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2);
399  BCI_SEND(GlobalBitmapDescriptor);
400 }
401 
402 static void savagefb_set_clip(struct fb_info *info)
403 {
404  struct savagefb_par *par = info->par;
405  int cmd;
406 
408  par->bci_ptr = 0;
409  par->SavageWaitFifo(par,3);
410  BCI_SEND(cmd);
411  BCI_SEND(BCI_CLIP_TL(0, 0));
412  BCI_SEND(BCI_CLIP_BR(0xfff, 0xfff));
413 }
414 #else
415 static void SavageSetup2DEngine(struct savagefb_par *par) {}
416 
417 #endif
418 
419 static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1,
420  int min_n2, int max_n2, long freq_min,
421  long freq_max, unsigned int *mdiv,
422  unsigned int *ndiv, unsigned int *r)
423 {
424  long diff, best_diff;
425  unsigned int m;
426  unsigned char n1, n2, best_n1=16+2, best_n2=2, best_m=125+2;
427 
428  if (freq < freq_min / (1 << max_n2)) {
429  printk(KERN_ERR "invalid frequency %ld Khz\n", freq);
430  freq = freq_min / (1 << max_n2);
431  }
432  if (freq > freq_max / (1 << min_n2)) {
433  printk(KERN_ERR "invalid frequency %ld Khz\n", freq);
434  freq = freq_max / (1 << min_n2);
435  }
436 
437  /* work out suitable timings */
438  best_diff = freq;
439 
440  for (n2=min_n2; n2<=max_n2; n2++) {
441  for (n1=min_n1+2; n1<=max_n1+2; n1++) {
442  m = (freq * n1 * (1 << n2) + HALF_BASE_FREQ) /
443  BASE_FREQ;
444  if (m < min_m+2 || m > 127+2)
445  continue;
446  if ((m * BASE_FREQ >= freq_min * n1) &&
447  (m * BASE_FREQ <= freq_max * n1)) {
448  diff = freq * (1 << n2) * n1 - BASE_FREQ * m;
449  if (diff < 0)
450  diff = -diff;
451  if (diff < best_diff) {
452  best_diff = diff;
453  best_m = m;
454  best_n1 = n1;
455  best_n2 = n2;
456  }
457  }
458  }
459  }
460 
461  *ndiv = best_n1 - 2;
462  *r = best_n2;
463  *mdiv = best_m - 2;
464 }
465 
466 static int common_calc_clock(long freq, int min_m, int min_n1, int max_n1,
467  int min_n2, int max_n2, long freq_min,
468  long freq_max, unsigned char *mdiv,
469  unsigned char *ndiv)
470 {
471  long diff, best_diff;
472  unsigned int m;
473  unsigned char n1, n2;
474  unsigned char best_n1 = 16+2, best_n2 = 2, best_m = 125+2;
475 
476  best_diff = freq;
477 
478  for (n2 = min_n2; n2 <= max_n2; n2++) {
479  for (n1 = min_n1+2; n1 <= max_n1+2; n1++) {
480  m = (freq * n1 * (1 << n2) + HALF_BASE_FREQ) /
481  BASE_FREQ;
482  if (m < min_m + 2 || m > 127+2)
483  continue;
484  if ((m * BASE_FREQ >= freq_min * n1) &&
485  (m * BASE_FREQ <= freq_max * n1)) {
486  diff = freq * (1 << n2) * n1 - BASE_FREQ * m;
487  if (diff < 0)
488  diff = -diff;
489  if (diff < best_diff) {
490  best_diff = diff;
491  best_m = m;
492  best_n1 = n1;
493  best_n2 = n2;
494  }
495  }
496  }
497  }
498 
499  if (max_n1 == 63)
500  *ndiv = (best_n1 - 2) | (best_n2 << 6);
501  else
502  *ndiv = (best_n1 - 2) | (best_n2 << 5);
503 
504  *mdiv = best_m - 2;
505 
506  return 0;
507 }
508 
509 #ifdef SAVAGEFB_DEBUG
510 /* This function is used to debug, it prints out the contents of s3 regs */
511 
512 static void SavagePrintRegs(struct savagefb_par *par)
513 {
514  unsigned char i;
515  int vgaCRIndex = 0x3d4;
516  int vgaCRReg = 0x3d5;
517 
518  printk(KERN_DEBUG "SR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE "
519  "xF");
520 
521  for (i = 0; i < 0x70; i++) {
522  if (!(i % 16))
523  printk(KERN_DEBUG "\nSR%xx ", i >> 4);
524  vga_out8(0x3c4, i, par);
525  printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par));
526  }
527 
528  printk(KERN_DEBUG "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "
529  "xD xE xF");
530 
531  for (i = 0; i < 0xB7; i++) {
532  if (!(i % 16))
533  printk(KERN_DEBUG "\nCR%xx ", i >> 4);
534  vga_out8(vgaCRIndex, i, par);
535  printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par));
536  }
537 
538  printk(KERN_DEBUG "\n\n");
539 }
540 #endif
541 
542 /* --------------------------------------------------------------------- */
543 
544 static void savage_get_default_par(struct savagefb_par *par, struct savage_reg *reg)
545 {
546  unsigned char cr3a, cr53, cr66;
547 
548  vga_out16(0x3d4, 0x4838, par);
549  vga_out16(0x3d4, 0xa039, par);
550  vga_out16(0x3c4, 0x0608, par);
551 
552  vga_out8(0x3d4, 0x66, par);
553  cr66 = vga_in8(0x3d5, par);
554  vga_out8(0x3d5, cr66 | 0x80, par);
555  vga_out8(0x3d4, 0x3a, par);
556  cr3a = vga_in8(0x3d5, par);
557  vga_out8(0x3d5, cr3a | 0x80, par);
558  vga_out8(0x3d4, 0x53, par);
559  cr53 = vga_in8(0x3d5, par);
560  vga_out8(0x3d5, cr53 & 0x7f, par);
561 
562  vga_out8(0x3d4, 0x66, par);
563  vga_out8(0x3d5, cr66, par);
564  vga_out8(0x3d4, 0x3a, par);
565  vga_out8(0x3d5, cr3a, par);
566 
567  vga_out8(0x3d4, 0x66, par);
568  vga_out8(0x3d5, cr66, par);
569  vga_out8(0x3d4, 0x3a, par);
570  vga_out8(0x3d5, cr3a, par);
571 
572  /* unlock extended seq regs */
573  vga_out8(0x3c4, 0x08, par);
574  reg->SR08 = vga_in8(0x3c5, par);
575  vga_out8(0x3c5, 0x06, par);
576 
577  /* now save all the extended regs we need */
578  vga_out8(0x3d4, 0x31, par);
579  reg->CR31 = vga_in8(0x3d5, par);
580  vga_out8(0x3d4, 0x32, par);
581  reg->CR32 = vga_in8(0x3d5, par);
582  vga_out8(0x3d4, 0x34, par);
583  reg->CR34 = vga_in8(0x3d5, par);
584  vga_out8(0x3d4, 0x36, par);
585  reg->CR36 = vga_in8(0x3d5, par);
586  vga_out8(0x3d4, 0x3a, par);
587  reg->CR3A = vga_in8(0x3d5, par);
588  vga_out8(0x3d4, 0x40, par);
589  reg->CR40 = vga_in8(0x3d5, par);
590  vga_out8(0x3d4, 0x42, par);
591  reg->CR42 = vga_in8(0x3d5, par);
592  vga_out8(0x3d4, 0x45, par);
593  reg->CR45 = vga_in8(0x3d5, par);
594  vga_out8(0x3d4, 0x50, par);
595  reg->CR50 = vga_in8(0x3d5, par);
596  vga_out8(0x3d4, 0x51, par);
597  reg->CR51 = vga_in8(0x3d5, par);
598  vga_out8(0x3d4, 0x53, par);
599  reg->CR53 = vga_in8(0x3d5, par);
600  vga_out8(0x3d4, 0x58, par);
601  reg->CR58 = vga_in8(0x3d5, par);
602  vga_out8(0x3d4, 0x60, par);
603  reg->CR60 = vga_in8(0x3d5, par);
604  vga_out8(0x3d4, 0x66, par);
605  reg->CR66 = vga_in8(0x3d5, par);
606  vga_out8(0x3d4, 0x67, par);
607  reg->CR67 = vga_in8(0x3d5, par);
608  vga_out8(0x3d4, 0x68, par);
609  reg->CR68 = vga_in8(0x3d5, par);
610  vga_out8(0x3d4, 0x69, par);
611  reg->CR69 = vga_in8(0x3d5, par);
612  vga_out8(0x3d4, 0x6f, par);
613  reg->CR6F = vga_in8(0x3d5, par);
614 
615  vga_out8(0x3d4, 0x33, par);
616  reg->CR33 = vga_in8(0x3d5, par);
617  vga_out8(0x3d4, 0x86, par);
618  reg->CR86 = vga_in8(0x3d5, par);
619  vga_out8(0x3d4, 0x88, par);
620  reg->CR88 = vga_in8(0x3d5, par);
621  vga_out8(0x3d4, 0x90, par);
622  reg->CR90 = vga_in8(0x3d5, par);
623  vga_out8(0x3d4, 0x91, par);
624  reg->CR91 = vga_in8(0x3d5, par);
625  vga_out8(0x3d4, 0xb0, par);
626  reg->CRB0 = vga_in8(0x3d5, par) | 0x80;
627 
628  /* extended mode timing regs */
629  vga_out8(0x3d4, 0x3b, par);
630  reg->CR3B = vga_in8(0x3d5, par);
631  vga_out8(0x3d4, 0x3c, par);
632  reg->CR3C = vga_in8(0x3d5, par);
633  vga_out8(0x3d4, 0x43, par);
634  reg->CR43 = vga_in8(0x3d5, par);
635  vga_out8(0x3d4, 0x5d, par);
636  reg->CR5D = vga_in8(0x3d5, par);
637  vga_out8(0x3d4, 0x5e, par);
638  reg->CR5E = vga_in8(0x3d5, par);
639  vga_out8(0x3d4, 0x65, par);
640  reg->CR65 = vga_in8(0x3d5, par);
641 
642  /* save seq extended regs for DCLK PLL programming */
643  vga_out8(0x3c4, 0x0e, par);
644  reg->SR0E = vga_in8(0x3c5, par);
645  vga_out8(0x3c4, 0x0f, par);
646  reg->SR0F = vga_in8(0x3c5, par);
647  vga_out8(0x3c4, 0x10, par);
648  reg->SR10 = vga_in8(0x3c5, par);
649  vga_out8(0x3c4, 0x11, par);
650  reg->SR11 = vga_in8(0x3c5, par);
651  vga_out8(0x3c4, 0x12, par);
652  reg->SR12 = vga_in8(0x3c5, par);
653  vga_out8(0x3c4, 0x13, par);
654  reg->SR13 = vga_in8(0x3c5, par);
655  vga_out8(0x3c4, 0x29, par);
656  reg->SR29 = vga_in8(0x3c5, par);
657 
658  vga_out8(0x3c4, 0x15, par);
659  reg->SR15 = vga_in8(0x3c5, par);
660  vga_out8(0x3c4, 0x30, par);
661  reg->SR30 = vga_in8(0x3c5, par);
662  vga_out8(0x3c4, 0x18, par);
663  reg->SR18 = vga_in8(0x3c5, par);
664 
665  /* Save flat panel expansion registers. */
666  if (par->chip == S3_SAVAGE_MX) {
667  int i;
668 
669  for (i = 0; i < 8; i++) {
670  vga_out8(0x3c4, 0x54+i, par);
671  reg->SR54[i] = vga_in8(0x3c5, par);
672  }
673  }
674 
675  vga_out8(0x3d4, 0x66, par);
676  cr66 = vga_in8(0x3d5, par);
677  vga_out8(0x3d5, cr66 | 0x80, par);
678  vga_out8(0x3d4, 0x3a, par);
679  cr3a = vga_in8(0x3d5, par);
680  vga_out8(0x3d5, cr3a | 0x80, par);
681 
682  /* now save MIU regs */
683  if (par->chip != S3_SAVAGE_MX) {
684  reg->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);
685  reg->MMPR1 = savage_in32(MIU_CONTROL_REG, par);
686  reg->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);
687  reg->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);
688  }
689 
690  vga_out8(0x3d4, 0x3a, par);
691  vga_out8(0x3d5, cr3a, par);
692  vga_out8(0x3d4, 0x66, par);
693  vga_out8(0x3d5, cr66, par);
694 }
695 
696 static void savage_set_default_par(struct savagefb_par *par,
697  struct savage_reg *reg)
698 {
699  unsigned char cr3a, cr53, cr66;
700 
701  vga_out16(0x3d4, 0x4838, par);
702  vga_out16(0x3d4, 0xa039, par);
703  vga_out16(0x3c4, 0x0608, par);
704 
705  vga_out8(0x3d4, 0x66, par);
706  cr66 = vga_in8(0x3d5, par);
707  vga_out8(0x3d5, cr66 | 0x80, par);
708  vga_out8(0x3d4, 0x3a, par);
709  cr3a = vga_in8(0x3d5, par);
710  vga_out8(0x3d5, cr3a | 0x80, par);
711  vga_out8(0x3d4, 0x53, par);
712  cr53 = vga_in8(0x3d5, par);
713  vga_out8(0x3d5, cr53 & 0x7f, par);
714 
715  vga_out8(0x3d4, 0x66, par);
716  vga_out8(0x3d5, cr66, par);
717  vga_out8(0x3d4, 0x3a, par);
718  vga_out8(0x3d5, cr3a, par);
719 
720  vga_out8(0x3d4, 0x66, par);
721  vga_out8(0x3d5, cr66, par);
722  vga_out8(0x3d4, 0x3a, par);
723  vga_out8(0x3d5, cr3a, par);
724 
725  /* unlock extended seq regs */
726  vga_out8(0x3c4, 0x08, par);
727  vga_out8(0x3c5, reg->SR08, par);
728  vga_out8(0x3c5, 0x06, par);
729 
730  /* now restore all the extended regs we need */
731  vga_out8(0x3d4, 0x31, par);
732  vga_out8(0x3d5, reg->CR31, par);
733  vga_out8(0x3d4, 0x32, par);
734  vga_out8(0x3d5, reg->CR32, par);
735  vga_out8(0x3d4, 0x34, par);
736  vga_out8(0x3d5, reg->CR34, par);
737  vga_out8(0x3d4, 0x36, par);
738  vga_out8(0x3d5,reg->CR36, par);
739  vga_out8(0x3d4, 0x3a, par);
740  vga_out8(0x3d5, reg->CR3A, par);
741  vga_out8(0x3d4, 0x40, par);
742  vga_out8(0x3d5, reg->CR40, par);
743  vga_out8(0x3d4, 0x42, par);
744  vga_out8(0x3d5, reg->CR42, par);
745  vga_out8(0x3d4, 0x45, par);
746  vga_out8(0x3d5, reg->CR45, par);
747  vga_out8(0x3d4, 0x50, par);
748  vga_out8(0x3d5, reg->CR50, par);
749  vga_out8(0x3d4, 0x51, par);
750  vga_out8(0x3d5, reg->CR51, par);
751  vga_out8(0x3d4, 0x53, par);
752  vga_out8(0x3d5, reg->CR53, par);
753  vga_out8(0x3d4, 0x58, par);
754  vga_out8(0x3d5, reg->CR58, par);
755  vga_out8(0x3d4, 0x60, par);
756  vga_out8(0x3d5, reg->CR60, par);
757  vga_out8(0x3d4, 0x66, par);
758  vga_out8(0x3d5, reg->CR66, par);
759  vga_out8(0x3d4, 0x67, par);
760  vga_out8(0x3d5, reg->CR67, par);
761  vga_out8(0x3d4, 0x68, par);
762  vga_out8(0x3d5, reg->CR68, par);
763  vga_out8(0x3d4, 0x69, par);
764  vga_out8(0x3d5, reg->CR69, par);
765  vga_out8(0x3d4, 0x6f, par);
766  vga_out8(0x3d5, reg->CR6F, par);
767 
768  vga_out8(0x3d4, 0x33, par);
769  vga_out8(0x3d5, reg->CR33, par);
770  vga_out8(0x3d4, 0x86, par);
771  vga_out8(0x3d5, reg->CR86, par);
772  vga_out8(0x3d4, 0x88, par);
773  vga_out8(0x3d5, reg->CR88, par);
774  vga_out8(0x3d4, 0x90, par);
775  vga_out8(0x3d5, reg->CR90, par);
776  vga_out8(0x3d4, 0x91, par);
777  vga_out8(0x3d5, reg->CR91, par);
778  vga_out8(0x3d4, 0xb0, par);
779  vga_out8(0x3d5, reg->CRB0, par);
780 
781  /* extended mode timing regs */
782  vga_out8(0x3d4, 0x3b, par);
783  vga_out8(0x3d5, reg->CR3B, par);
784  vga_out8(0x3d4, 0x3c, par);
785  vga_out8(0x3d5, reg->CR3C, par);
786  vga_out8(0x3d4, 0x43, par);
787  vga_out8(0x3d5, reg->CR43, par);
788  vga_out8(0x3d4, 0x5d, par);
789  vga_out8(0x3d5, reg->CR5D, par);
790  vga_out8(0x3d4, 0x5e, par);
791  vga_out8(0x3d5, reg->CR5E, par);
792  vga_out8(0x3d4, 0x65, par);
793  vga_out8(0x3d5, reg->CR65, par);
794 
795  /* save seq extended regs for DCLK PLL programming */
796  vga_out8(0x3c4, 0x0e, par);
797  vga_out8(0x3c5, reg->SR0E, par);
798  vga_out8(0x3c4, 0x0f, par);
799  vga_out8(0x3c5, reg->SR0F, par);
800  vga_out8(0x3c4, 0x10, par);
801  vga_out8(0x3c5, reg->SR10, par);
802  vga_out8(0x3c4, 0x11, par);
803  vga_out8(0x3c5, reg->SR11, par);
804  vga_out8(0x3c4, 0x12, par);
805  vga_out8(0x3c5, reg->SR12, par);
806  vga_out8(0x3c4, 0x13, par);
807  vga_out8(0x3c5, reg->SR13, par);
808  vga_out8(0x3c4, 0x29, par);
809  vga_out8(0x3c5, reg->SR29, par);
810 
811  vga_out8(0x3c4, 0x15, par);
812  vga_out8(0x3c5, reg->SR15, par);
813  vga_out8(0x3c4, 0x30, par);
814  vga_out8(0x3c5, reg->SR30, par);
815  vga_out8(0x3c4, 0x18, par);
816  vga_out8(0x3c5, reg->SR18, par);
817 
818  /* Save flat panel expansion registers. */
819  if (par->chip == S3_SAVAGE_MX) {
820  int i;
821 
822  for (i = 0; i < 8; i++) {
823  vga_out8(0x3c4, 0x54+i, par);
824  vga_out8(0x3c5, reg->SR54[i], par);
825  }
826  }
827 
828  vga_out8(0x3d4, 0x66, par);
829  cr66 = vga_in8(0x3d5, par);
830  vga_out8(0x3d5, cr66 | 0x80, par);
831  vga_out8(0x3d4, 0x3a, par);
832  cr3a = vga_in8(0x3d5, par);
833  vga_out8(0x3d5, cr3a | 0x80, par);
834 
835  /* now save MIU regs */
836  if (par->chip != S3_SAVAGE_MX) {
837  savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par);
838  savage_out32(MIU_CONTROL_REG, reg->MMPR1, par);
839  savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par);
840  savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par);
841  }
842 
843  vga_out8(0x3d4, 0x3a, par);
844  vga_out8(0x3d5, cr3a, par);
845  vga_out8(0x3d4, 0x66, par);
846  vga_out8(0x3d5, cr66, par);
847 }
848 
849 static void savage_update_var(struct fb_var_screeninfo *var,
850  const struct fb_videomode *modedb)
851 {
852  var->xres = var->xres_virtual = modedb->xres;
853  var->yres = modedb->yres;
854  if (var->yres_virtual < var->yres)
855  var->yres_virtual = var->yres;
856  var->xoffset = var->yoffset = 0;
857  var->pixclock = modedb->pixclock;
858  var->left_margin = modedb->left_margin;
859  var->right_margin = modedb->right_margin;
860  var->upper_margin = modedb->upper_margin;
861  var->lower_margin = modedb->lower_margin;
862  var->hsync_len = modedb->hsync_len;
863  var->vsync_len = modedb->vsync_len;
864  var->sync = modedb->sync;
865  var->vmode = modedb->vmode;
866 }
867 
868 static int savagefb_check_var(struct fb_var_screeninfo *var,
869  struct fb_info *info)
870 {
871  struct savagefb_par *par = info->par;
872  int memlen, vramlen, mode_valid = 0;
873 
874  DBG("savagefb_check_var");
875 
876  var->transp.offset = 0;
877  var->transp.length = 0;
878  switch (var->bits_per_pixel) {
879  case 8:
880  var->red.offset = var->green.offset =
881  var->blue.offset = 0;
882  var->red.length = var->green.length =
883  var->blue.length = var->bits_per_pixel;
884  break;
885  case 16:
886  var->red.offset = 11;
887  var->red.length = 5;
888  var->green.offset = 5;
889  var->green.length = 6;
890  var->blue.offset = 0;
891  var->blue.length = 5;
892  break;
893  case 32:
894  var->transp.offset = 24;
895  var->transp.length = 8;
896  var->red.offset = 16;
897  var->red.length = 8;
898  var->green.offset = 8;
899  var->green.length = 8;
900  var->blue.offset = 0;
901  var->blue.length = 8;
902  break;
903 
904  default:
905  return -EINVAL;
906  }
907 
908  if (!info->monspecs.hfmax || !info->monspecs.vfmax ||
909  !info->monspecs.dclkmax || !fb_validate_mode(var, info))
910  mode_valid = 1;
911 
912  /* calculate modeline if supported by monitor */
913  if (!mode_valid && info->monspecs.gtf) {
914  if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))
915  mode_valid = 1;
916  }
917 
918  if (!mode_valid) {
919  const struct fb_videomode *mode;
920 
921  mode = fb_find_best_mode(var, &info->modelist);
922  if (mode) {
923  savage_update_var(var, mode);
924  mode_valid = 1;
925  }
926  }
927 
928  if (!mode_valid && info->monspecs.modedb_len)
929  return -EINVAL;
930 
931  /* Is the mode larger than the LCD panel? */
932  if (par->SavagePanelWidth &&
933  (var->xres > par->SavagePanelWidth ||
934  var->yres > par->SavagePanelHeight)) {
935  printk(KERN_INFO "Mode (%dx%d) larger than the LCD panel "
936  "(%dx%d)\n", var->xres, var->yres,
937  par->SavagePanelWidth,
938  par->SavagePanelHeight);
939  return -1;
940  }
941 
942  if (var->yres_virtual < var->yres)
943  var->yres_virtual = var->yres;
944  if (var->xres_virtual < var->xres)
945  var->xres_virtual = var->xres;
946 
947  vramlen = info->fix.smem_len;
948 
949  memlen = var->xres_virtual * var->bits_per_pixel *
950  var->yres_virtual / 8;
951  if (memlen > vramlen) {
952  var->yres_virtual = vramlen * 8 /
953  (var->xres_virtual * var->bits_per_pixel);
954  memlen = var->xres_virtual * var->bits_per_pixel *
955  var->yres_virtual / 8;
956  }
957 
958  /* we must round yres/xres down, we already rounded y/xres_virtual up
959  if it was possible. We should return -EINVAL, but I disagree */
960  if (var->yres_virtual < var->yres)
961  var->yres = var->yres_virtual;
962  if (var->xres_virtual < var->xres)
963  var->xres = var->xres_virtual;
964  if (var->xoffset + var->xres > var->xres_virtual)
965  var->xoffset = var->xres_virtual - var->xres;
966  if (var->yoffset + var->yres > var->yres_virtual)
967  var->yoffset = var->yres_virtual - var->yres;
968 
969  return 0;
970 }
971 
972 
973 static int savagefb_decode_var(struct fb_var_screeninfo *var,
974  struct savagefb_par *par,
975  struct savage_reg *reg)
976 {
977  struct xtimings timings;
978  int width, dclk, i, j; /*, refresh; */
979  unsigned int m, n, r;
980  unsigned char tmp = 0;
981  unsigned int pixclock = var->pixclock;
982 
983  DBG("savagefb_decode_var");
984 
985  memset(&timings, 0, sizeof(timings));
986 
987  if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */
988  timings.Clock = 1000000000 / pixclock;
989  if (timings.Clock < 1) timings.Clock = 1;
990  timings.dblscan = var->vmode & FB_VMODE_DOUBLE;
991  timings.interlaced = var->vmode & FB_VMODE_INTERLACED;
992  timings.HDisplay = var->xres;
993  timings.HSyncStart = timings.HDisplay + var->right_margin;
994  timings.HSyncEnd = timings.HSyncStart + var->hsync_len;
995  timings.HTotal = timings.HSyncEnd + var->left_margin;
996  timings.VDisplay = var->yres;
997  timings.VSyncStart = timings.VDisplay + var->lower_margin;
998  timings.VSyncEnd = timings.VSyncStart + var->vsync_len;
999  timings.VTotal = timings.VSyncEnd + var->upper_margin;
1000  timings.sync = var->sync;
1001 
1002 
1003  par->depth = var->bits_per_pixel;
1004  par->vwidth = var->xres_virtual;
1005 
1006  if (var->bits_per_pixel == 16 && par->chip == S3_SAVAGE3D) {
1007  timings.HDisplay *= 2;
1008  timings.HSyncStart *= 2;
1009  timings.HSyncEnd *= 2;
1010  timings.HTotal *= 2;
1011  }
1012 
1013  /*
1014  * This will allocate the datastructure and initialize all of the
1015  * generic VGA registers.
1016  */
1017  vgaHWInit(var, par, &timings, reg);
1018 
1019  /* We need to set CR67 whether or not we use the BIOS. */
1020 
1021  dclk = timings.Clock;
1022  reg->CR67 = 0x00;
1023 
1024  switch(var->bits_per_pixel) {
1025  case 8:
1026  if ((par->chip == S3_SAVAGE2000) && (dclk >= 230000))
1027  reg->CR67 = 0x10; /* 8bpp, 2 pixels/clock */
1028  else
1029  reg->CR67 = 0x00; /* 8bpp, 1 pixel/clock */
1030  break;
1031  case 15:
1032  if (S3_SAVAGE_MOBILE_SERIES(par->chip) ||
1033  ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)))
1034  reg->CR67 = 0x30; /* 15bpp, 2 pixel/clock */
1035  else
1036  reg->CR67 = 0x20; /* 15bpp, 1 pixels/clock */
1037  break;
1038  case 16:
1039  if (S3_SAVAGE_MOBILE_SERIES(par->chip) ||
1040  ((par->chip == S3_SAVAGE2000) && (dclk >= 230000)))
1041  reg->CR67 = 0x50; /* 16bpp, 2 pixel/clock */
1042  else
1043  reg->CR67 = 0x40; /* 16bpp, 1 pixels/clock */
1044  break;
1045  case 24:
1046  reg->CR67 = 0x70;
1047  break;
1048  case 32:
1049  reg->CR67 = 0xd0;
1050  break;
1051  }
1052 
1053  /*
1054  * Either BIOS use is disabled, or we failed to find a suitable
1055  * match. Fall back to traditional register-crunching.
1056  */
1057 
1058  vga_out8(0x3d4, 0x3a, par);
1059  tmp = vga_in8(0x3d5, par);
1060  if (1 /*FIXME:psav->pci_burst*/)
1061  reg->CR3A = (tmp & 0x7f) | 0x15;
1062  else
1063  reg->CR3A = tmp | 0x95;
1064 
1065  reg->CR53 = 0x00;
1066  reg->CR31 = 0x8c;
1067  reg->CR66 = 0x89;
1068 
1069  vga_out8(0x3d4, 0x58, par);
1070  reg->CR58 = vga_in8(0x3d5, par) & 0x80;
1071  reg->CR58 |= 0x13;
1072 
1073  reg->SR15 = 0x03 | 0x80;
1074  reg->SR18 = 0x00;
1075  reg->CR43 = reg->CR45 = reg->CR65 = 0x00;
1076 
1077  vga_out8(0x3d4, 0x40, par);
1078  reg->CR40 = vga_in8(0x3d5, par) & ~0x01;
1079 
1080  reg->MMPR0 = 0x010400;
1081  reg->MMPR1 = 0x00;
1082  reg->MMPR2 = 0x0808;
1083  reg->MMPR3 = 0x08080810;
1084 
1085  SavageCalcClock(dclk, 1, 1, 127, 0, 4, 180000, 360000, &m, &n, &r);
1086  /* m = 107; n = 4; r = 2; */
1087 
1088  if (par->MCLK <= 0) {
1089  reg->SR10 = 255;
1090  reg->SR11 = 255;
1091  } else {
1092  common_calc_clock(par->MCLK, 1, 1, 31, 0, 3, 135000, 270000,
1093  &reg->SR11, &reg->SR10);
1094  /* reg->SR10 = 80; // MCLK == 286000 */
1095  /* reg->SR11 = 125; */
1096  }
1097 
1098  reg->SR12 = (r << 6) | (n & 0x3f);
1099  reg->SR13 = m & 0xff;
1100  reg->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2;
1101 
1102  if (var->bits_per_pixel < 24)
1103  reg->MMPR0 -= 0x8000;
1104  else
1105  reg->MMPR0 -= 0x4000;
1106 
1107  if (timings.interlaced)
1108  reg->CR42 = 0x20;
1109  else
1110  reg->CR42 = 0x00;
1111 
1112  reg->CR34 = 0x10; /* display fifo */
1113 
1114  i = ((((timings.HTotal >> 3) - 5) & 0x100) >> 8) |
1115  ((((timings.HDisplay >> 3) - 1) & 0x100) >> 7) |
1116  ((((timings.HSyncStart >> 3) - 1) & 0x100) >> 6) |
1117  ((timings.HSyncStart & 0x800) >> 7);
1118 
1119  if ((timings.HSyncEnd >> 3) - (timings.HSyncStart >> 3) > 64)
1120  i |= 0x08;
1121  if ((timings.HSyncEnd >> 3) - (timings.HSyncStart >> 3) > 32)
1122  i |= 0x20;
1123 
1124  j = (reg->CRTC[0] + ((i & 0x01) << 8) +
1125  reg->CRTC[4] + ((i & 0x10) << 4) + 1) / 2;
1126 
1127  if (j - (reg->CRTC[4] + ((i & 0x10) << 4)) < 4) {
1128  if (reg->CRTC[4] + ((i & 0x10) << 4) + 4 <=
1129  reg->CRTC[0] + ((i & 0x01) << 8))
1130  j = reg->CRTC[4] + ((i & 0x10) << 4) + 4;
1131  else
1132  j = reg->CRTC[0] + ((i & 0x01) << 8) + 1;
1133  }
1134 
1135  reg->CR3B = j & 0xff;
1136  i |= (j & 0x100) >> 2;
1137  reg->CR3C = (reg->CRTC[0] + ((i & 0x01) << 8)) / 2;
1138  reg->CR5D = i;
1139  reg->CR5E = (((timings.VTotal - 2) & 0x400) >> 10) |
1140  (((timings.VDisplay - 1) & 0x400) >> 9) |
1141  (((timings.VSyncStart) & 0x400) >> 8) |
1142  (((timings.VSyncStart) & 0x400) >> 6) | 0x40;
1143  width = (var->xres_virtual * ((var->bits_per_pixel+7) / 8)) >> 3;
1144  reg->CR91 = reg->CRTC[19] = 0xff & width;
1145  reg->CR51 = (0x300 & width) >> 4;
1146  reg->CR90 = 0x80 | (width >> 8);
1147  reg->MiscOutReg |= 0x0c;
1148 
1149  /* Set frame buffer description. */
1150 
1151  if (var->bits_per_pixel <= 8)
1152  reg->CR50 = 0;
1153  else if (var->bits_per_pixel <= 16)
1154  reg->CR50 = 0x10;
1155  else
1156  reg->CR50 = 0x30;
1157 
1158  if (var->xres_virtual <= 640)
1159  reg->CR50 |= 0x40;
1160  else if (var->xres_virtual == 800)
1161  reg->CR50 |= 0x80;
1162  else if (var->xres_virtual == 1024)
1163  reg->CR50 |= 0x00;
1164  else if (var->xres_virtual == 1152)
1165  reg->CR50 |= 0x01;
1166  else if (var->xres_virtual == 1280)
1167  reg->CR50 |= 0xc0;
1168  else if (var->xres_virtual == 1600)
1169  reg->CR50 |= 0x81;
1170  else
1171  reg->CR50 |= 0xc1; /* Use GBD */
1172 
1173  if (par->chip == S3_SAVAGE2000)
1174  reg->CR33 = 0x08;
1175  else
1176  reg->CR33 = 0x20;
1177 
1178  reg->CRTC[0x17] = 0xeb;
1179 
1180  reg->CR67 |= 1;
1181 
1182  vga_out8(0x3d4, 0x36, par);
1183  reg->CR36 = vga_in8(0x3d5, par);
1184  vga_out8(0x3d4, 0x68, par);
1185  reg->CR68 = vga_in8(0x3d5, par);
1186  reg->CR69 = 0;
1187  vga_out8(0x3d4, 0x6f, par);
1188  reg->CR6F = vga_in8(0x3d5, par);
1189  vga_out8(0x3d4, 0x86, par);
1190  reg->CR86 = vga_in8(0x3d5, par);
1191  vga_out8(0x3d4, 0x88, par);
1192  reg->CR88 = vga_in8(0x3d5, par) | 0x08;
1193  vga_out8(0x3d4, 0xb0, par);
1194  reg->CRB0 = vga_in8(0x3d5, par) | 0x80;
1195 
1196  return 0;
1197 }
1198 
1199 /* --------------------------------------------------------------------- */
1200 
1201 /*
1202  * Set a single color register. Return != 0 for invalid regno.
1203  */
1204 static int savagefb_setcolreg(unsigned regno,
1205  unsigned red,
1206  unsigned green,
1207  unsigned blue,
1208  unsigned transp,
1209  struct fb_info *info)
1210 {
1211  struct savagefb_par *par = info->par;
1212 
1213  if (regno >= NR_PALETTE)
1214  return -EINVAL;
1215 
1216  par->palette[regno].red = red;
1217  par->palette[regno].green = green;
1218  par->palette[regno].blue = blue;
1219  par->palette[regno].transp = transp;
1220 
1221  switch (info->var.bits_per_pixel) {
1222  case 8:
1223  vga_out8(0x3c8, regno, par);
1224 
1225  vga_out8(0x3c9, red >> 10, par);
1226  vga_out8(0x3c9, green >> 10, par);
1227  vga_out8(0x3c9, blue >> 10, par);
1228  break;
1229 
1230  case 16:
1231  if (regno < 16)
1232  ((u32 *)info->pseudo_palette)[regno] =
1233  ((red & 0xf800) ) |
1234  ((green & 0xfc00) >> 5) |
1235  ((blue & 0xf800) >> 11);
1236  break;
1237 
1238  case 24:
1239  if (regno < 16)
1240  ((u32 *)info->pseudo_palette)[regno] =
1241  ((red & 0xff00) << 8) |
1242  ((green & 0xff00) ) |
1243  ((blue & 0xff00) >> 8);
1244  break;
1245  case 32:
1246  if (regno < 16)
1247  ((u32 *)info->pseudo_palette)[regno] =
1248  ((transp & 0xff00) << 16) |
1249  ((red & 0xff00) << 8) |
1250  ((green & 0xff00) ) |
1251  ((blue & 0xff00) >> 8);
1252  break;
1253 
1254  default:
1255  return 1;
1256  }
1257 
1258  return 0;
1259 }
1260 
1261 static void savagefb_set_par_int(struct savagefb_par *par, struct savage_reg *reg)
1262 {
1263  unsigned char tmp, cr3a, cr66, cr67;
1264 
1265  DBG("savagefb_set_par_int");
1266 
1267  par->SavageWaitIdle(par);
1268 
1269  vga_out8(0x3c2, 0x23, par);
1270 
1271  vga_out16(0x3d4, 0x4838, par);
1272  vga_out16(0x3d4, 0xa539, par);
1273  vga_out16(0x3c4, 0x0608, par);
1274 
1275  vgaHWProtect(par, 1);
1276 
1277  /*
1278  * Some Savage/MX and /IX systems go nuts when trying to exit the
1279  * server after WindowMaker has displayed a gradient background. I
1280  * haven't been able to find what causes it, but a non-destructive
1281  * switch to mode 3 here seems to eliminate the issue.
1282  */
1283 
1284  VerticalRetraceWait(par);
1285  vga_out8(0x3d4, 0x67, par);
1286  cr67 = vga_in8(0x3d5, par);
1287  vga_out8(0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */
1288 
1289  vga_out8(0x3d4, 0x23, par);
1290  vga_out8(0x3d5, 0x00, par);
1291  vga_out8(0x3d4, 0x26, par);
1292  vga_out8(0x3d5, 0x00, par);
1293 
1294  /* restore extended regs */
1295  vga_out8(0x3d4, 0x66, par);
1296  vga_out8(0x3d5, reg->CR66, par);
1297  vga_out8(0x3d4, 0x3a, par);
1298  vga_out8(0x3d5, reg->CR3A, par);
1299  vga_out8(0x3d4, 0x31, par);
1300  vga_out8(0x3d5, reg->CR31, par);
1301  vga_out8(0x3d4, 0x32, par);
1302  vga_out8(0x3d5, reg->CR32, par);
1303  vga_out8(0x3d4, 0x58, par);
1304  vga_out8(0x3d5, reg->CR58, par);
1305  vga_out8(0x3d4, 0x53, par);
1306  vga_out8(0x3d5, reg->CR53 & 0x7f, par);
1307 
1308  vga_out16(0x3c4, 0x0608, par);
1309 
1310  /* Restore DCLK registers. */
1311 
1312  vga_out8(0x3c4, 0x0e, par);
1313  vga_out8(0x3c5, reg->SR0E, par);
1314  vga_out8(0x3c4, 0x0f, par);
1315  vga_out8(0x3c5, reg->SR0F, par);
1316  vga_out8(0x3c4, 0x29, par);
1317  vga_out8(0x3c5, reg->SR29, par);
1318  vga_out8(0x3c4, 0x15, par);
1319  vga_out8(0x3c5, reg->SR15, par);
1320 
1321  /* Restore flat panel expansion registers. */
1322  if (par->chip == S3_SAVAGE_MX) {
1323  int i;
1324 
1325  for (i = 0; i < 8; i++) {
1326  vga_out8(0x3c4, 0x54+i, par);
1327  vga_out8(0x3c5, reg->SR54[i], par);
1328  }
1329  }
1330 
1331  vgaHWRestore (par, reg);
1332 
1333  /* extended mode timing registers */
1334  vga_out8(0x3d4, 0x53, par);
1335  vga_out8(0x3d5, reg->CR53, par);
1336  vga_out8(0x3d4, 0x5d, par);
1337  vga_out8(0x3d5, reg->CR5D, par);
1338  vga_out8(0x3d4, 0x5e, par);
1339  vga_out8(0x3d5, reg->CR5E, par);
1340  vga_out8(0x3d4, 0x3b, par);
1341  vga_out8(0x3d5, reg->CR3B, par);
1342  vga_out8(0x3d4, 0x3c, par);
1343  vga_out8(0x3d5, reg->CR3C, par);
1344  vga_out8(0x3d4, 0x43, par);
1345  vga_out8(0x3d5, reg->CR43, par);
1346  vga_out8(0x3d4, 0x65, par);
1347  vga_out8(0x3d5, reg->CR65, par);
1348 
1349  /* restore the desired video mode with cr67 */
1350  vga_out8(0x3d4, 0x67, par);
1351  /* following part not present in X11 driver */
1352  cr67 = vga_in8(0x3d5, par) & 0xf;
1353  vga_out8(0x3d5, 0x50 | cr67, par);
1354  mdelay(10);
1355  vga_out8(0x3d4, 0x67, par);
1356  /* end of part */
1357  vga_out8(0x3d5, reg->CR67 & ~0x0c, par);
1358 
1359  /* other mode timing and extended regs */
1360  vga_out8(0x3d4, 0x34, par);
1361  vga_out8(0x3d5, reg->CR34, par);
1362  vga_out8(0x3d4, 0x40, par);
1363  vga_out8(0x3d5, reg->CR40, par);
1364  vga_out8(0x3d4, 0x42, par);
1365  vga_out8(0x3d5, reg->CR42, par);
1366  vga_out8(0x3d4, 0x45, par);
1367  vga_out8(0x3d5, reg->CR45, par);
1368  vga_out8(0x3d4, 0x50, par);
1369  vga_out8(0x3d5, reg->CR50, par);
1370  vga_out8(0x3d4, 0x51, par);
1371  vga_out8(0x3d5, reg->CR51, par);
1372 
1373  /* memory timings */
1374  vga_out8(0x3d4, 0x36, par);
1375  vga_out8(0x3d5, reg->CR36, par);
1376  vga_out8(0x3d4, 0x60, par);
1377  vga_out8(0x3d5, reg->CR60, par);
1378  vga_out8(0x3d4, 0x68, par);
1379  vga_out8(0x3d5, reg->CR68, par);
1380  vga_out8(0x3d4, 0x69, par);
1381  vga_out8(0x3d5, reg->CR69, par);
1382  vga_out8(0x3d4, 0x6f, par);
1383  vga_out8(0x3d5, reg->CR6F, par);
1384 
1385  vga_out8(0x3d4, 0x33, par);
1386  vga_out8(0x3d5, reg->CR33, par);
1387  vga_out8(0x3d4, 0x86, par);
1388  vga_out8(0x3d5, reg->CR86, par);
1389  vga_out8(0x3d4, 0x88, par);
1390  vga_out8(0x3d5, reg->CR88, par);
1391  vga_out8(0x3d4, 0x90, par);
1392  vga_out8(0x3d5, reg->CR90, par);
1393  vga_out8(0x3d4, 0x91, par);
1394  vga_out8(0x3d5, reg->CR91, par);
1395 
1396  if (par->chip == S3_SAVAGE4) {
1397  vga_out8(0x3d4, 0xb0, par);
1398  vga_out8(0x3d5, reg->CRB0, par);
1399  }
1400 
1401  vga_out8(0x3d4, 0x32, par);
1402  vga_out8(0x3d5, reg->CR32, par);
1403 
1404  /* unlock extended seq regs */
1405  vga_out8(0x3c4, 0x08, par);
1406  vga_out8(0x3c5, 0x06, par);
1407 
1408  /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates
1409  * that we should leave the default SR10 and SR11 values there.
1410  */
1411  if (reg->SR10 != 255) {
1412  vga_out8(0x3c4, 0x10, par);
1413  vga_out8(0x3c5, reg->SR10, par);
1414  vga_out8(0x3c4, 0x11, par);
1415  vga_out8(0x3c5, reg->SR11, par);
1416  }
1417 
1418  /* restore extended seq regs for dclk */
1419  vga_out8(0x3c4, 0x0e, par);
1420  vga_out8(0x3c5, reg->SR0E, par);
1421  vga_out8(0x3c4, 0x0f, par);
1422  vga_out8(0x3c5, reg->SR0F, par);
1423  vga_out8(0x3c4, 0x12, par);
1424  vga_out8(0x3c5, reg->SR12, par);
1425  vga_out8(0x3c4, 0x13, par);
1426  vga_out8(0x3c5, reg->SR13, par);
1427  vga_out8(0x3c4, 0x29, par);
1428  vga_out8(0x3c5, reg->SR29, par);
1429  vga_out8(0x3c4, 0x18, par);
1430  vga_out8(0x3c5, reg->SR18, par);
1431 
1432  /* load new m, n pll values for dclk & mclk */
1433  vga_out8(0x3c4, 0x15, par);
1434  tmp = vga_in8(0x3c5, par) & ~0x21;
1435 
1436  vga_out8(0x3c5, tmp | 0x03, par);
1437  vga_out8(0x3c5, tmp | 0x23, par);
1438  vga_out8(0x3c5, tmp | 0x03, par);
1439  vga_out8(0x3c5, reg->SR15, par);
1440  udelay(100);
1441 
1442  vga_out8(0x3c4, 0x30, par);
1443  vga_out8(0x3c5, reg->SR30, par);
1444  vga_out8(0x3c4, 0x08, par);
1445  vga_out8(0x3c5, reg->SR08, par);
1446 
1447  /* now write out cr67 in full, possibly starting STREAMS */
1448  VerticalRetraceWait(par);
1449  vga_out8(0x3d4, 0x67, par);
1450  vga_out8(0x3d5, reg->CR67, par);
1451 
1452  vga_out8(0x3d4, 0x66, par);
1453  cr66 = vga_in8(0x3d5, par);
1454  vga_out8(0x3d5, cr66 | 0x80, par);
1455  vga_out8(0x3d4, 0x3a, par);
1456  cr3a = vga_in8(0x3d5, par);
1457  vga_out8(0x3d5, cr3a | 0x80, par);
1458 
1459  if (par->chip != S3_SAVAGE_MX) {
1460  VerticalRetraceWait(par);
1461  savage_out32(FIFO_CONTROL_REG, reg->MMPR0, par);
1462  par->SavageWaitIdle(par);
1463  savage_out32(MIU_CONTROL_REG, reg->MMPR1, par);
1464  par->SavageWaitIdle(par);
1465  savage_out32(STREAMS_TIMEOUT_REG, reg->MMPR2, par);
1466  par->SavageWaitIdle(par);
1467  savage_out32(MISC_TIMEOUT_REG, reg->MMPR3, par);
1468  }
1469 
1470  vga_out8(0x3d4, 0x66, par);
1471  vga_out8(0x3d5, cr66, par);
1472  vga_out8(0x3d4, 0x3a, par);
1473  vga_out8(0x3d5, cr3a, par);
1474 
1475  SavageSetup2DEngine(par);
1476  vgaHWProtect(par, 0);
1477 }
1478 
1479 static void savagefb_update_start(struct savagefb_par *par, int base)
1480 {
1481  /* program the start address registers */
1482  vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
1483  vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
1484  vga_out8(0x3d4, 0x69, par);
1485  vga_out8(0x3d5, (base & 0x7f0000) >> 16, par);
1486 }
1487 
1488 
1489 static void savagefb_set_fix(struct fb_info *info)
1490 {
1491  info->fix.line_length = info->var.xres_virtual *
1492  info->var.bits_per_pixel / 8;
1493 
1494  if (info->var.bits_per_pixel == 8) {
1495  info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1496  info->fix.xpanstep = 4;
1497  } else {
1498  info->fix.visual = FB_VISUAL_TRUECOLOR;
1499  info->fix.xpanstep = 2;
1500  }
1501 
1502 }
1503 
1504 static int savagefb_set_par(struct fb_info *info)
1505 {
1506  struct savagefb_par *par = info->par;
1507  struct fb_var_screeninfo *var = &info->var;
1508  int err;
1509 
1510  DBG("savagefb_set_par");
1511  err = savagefb_decode_var(var, par, &par->state);
1512  if (err)
1513  return err;
1514 
1515  if (par->dacSpeedBpp <= 0) {
1516  if (var->bits_per_pixel > 24)
1517  par->dacSpeedBpp = par->clock[3];
1518  else if (var->bits_per_pixel >= 24)
1519  par->dacSpeedBpp = par->clock[2];
1520  else if ((var->bits_per_pixel > 8) && (var->bits_per_pixel < 24))
1521  par->dacSpeedBpp = par->clock[1];
1522  else if (var->bits_per_pixel <= 8)
1523  par->dacSpeedBpp = par->clock[0];
1524  }
1525 
1526  /* Set ramdac limits */
1527  par->maxClock = par->dacSpeedBpp;
1528  par->minClock = 10000;
1529 
1530  savagefb_set_par_int(par, &par->state);
1531  fb_set_cmap(&info->cmap, info);
1532  savagefb_set_fix(info);
1533  savagefb_set_clip(info);
1534 
1535  SavagePrintRegs(par);
1536  return 0;
1537 }
1538 
1539 /*
1540  * Pan or Wrap the Display
1541  */
1542 static int savagefb_pan_display(struct fb_var_screeninfo *var,
1543  struct fb_info *info)
1544 {
1545  struct savagefb_par *par = info->par;
1546  int base;
1547 
1548  base = (var->yoffset * info->fix.line_length
1549  + (var->xoffset & ~1) * ((info->var.bits_per_pixel+7) / 8)) >> 2;
1550 
1551  savagefb_update_start(par, base);
1552  return 0;
1553 }
1554 
1555 static int savagefb_blank(int blank, struct fb_info *info)
1556 {
1557  struct savagefb_par *par = info->par;
1558  u8 sr8 = 0, srd = 0;
1559 
1560  if (par->display_type == DISP_CRT) {
1561  vga_out8(0x3c4, 0x08, par);
1562  sr8 = vga_in8(0x3c5, par);
1563  sr8 |= 0x06;
1564  vga_out8(0x3c5, sr8, par);
1565  vga_out8(0x3c4, 0x0d, par);
1566  srd = vga_in8(0x3c5, par);
1567  srd &= 0x50;
1568 
1569  switch (blank) {
1570  case FB_BLANK_UNBLANK:
1571  case FB_BLANK_NORMAL:
1572  break;
1574  srd |= 0x10;
1575  break;
1577  srd |= 0x40;
1578  break;
1579  case FB_BLANK_POWERDOWN:
1580  srd |= 0x50;
1581  break;
1582  }
1583 
1584  vga_out8(0x3c4, 0x0d, par);
1585  vga_out8(0x3c5, srd, par);
1586  }
1587 
1588  if (par->display_type == DISP_LCD ||
1589  par->display_type == DISP_DFP) {
1590  switch(blank) {
1591  case FB_BLANK_UNBLANK:
1592  case FB_BLANK_NORMAL:
1593  vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
1594  vga_out8(0x3c5, vga_in8(0x3c5, par) | 0x10, par);
1595  break;
1598  case FB_BLANK_POWERDOWN:
1599  vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
1600  vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x10, par);
1601  break;
1602  }
1603  }
1604 
1605  return (blank == FB_BLANK_NORMAL) ? 1 : 0;
1606 }
1607 
1608 static int savagefb_open(struct fb_info *info, int user)
1609 {
1610  struct savagefb_par *par = info->par;
1611 
1612  mutex_lock(&par->open_lock);
1613 
1614  if (!par->open_count) {
1615  memset(&par->vgastate, 0, sizeof(par->vgastate));
1616  par->vgastate.flags = VGA_SAVE_CMAP | VGA_SAVE_FONTS |
1617  VGA_SAVE_MODE;
1618  par->vgastate.vgabase = par->mmio.vbase + 0x8000;
1619  save_vga(&par->vgastate);
1620  savage_get_default_par(par, &par->initial);
1621  }
1622 
1623  par->open_count++;
1624  mutex_unlock(&par->open_lock);
1625  return 0;
1626 }
1627 
1628 static int savagefb_release(struct fb_info *info, int user)
1629 {
1630  struct savagefb_par *par = info->par;
1631 
1632  mutex_lock(&par->open_lock);
1633 
1634  if (par->open_count == 1) {
1635  savage_set_default_par(par, &par->initial);
1636  restore_vga(&par->vgastate);
1637  }
1638 
1639  par->open_count--;
1640  mutex_unlock(&par->open_lock);
1641  return 0;
1642 }
1643 
1644 static struct fb_ops savagefb_ops = {
1645  .owner = THIS_MODULE,
1646  .fb_open = savagefb_open,
1647  .fb_release = savagefb_release,
1648  .fb_check_var = savagefb_check_var,
1649  .fb_set_par = savagefb_set_par,
1650  .fb_setcolreg = savagefb_setcolreg,
1651  .fb_pan_display = savagefb_pan_display,
1652  .fb_blank = savagefb_blank,
1653 #if defined(CONFIG_FB_SAVAGE_ACCEL)
1654  .fb_fillrect = savagefb_fillrect,
1655  .fb_copyarea = savagefb_copyarea,
1656  .fb_imageblit = savagefb_imageblit,
1657  .fb_sync = savagefb_sync,
1658 #else
1659  .fb_fillrect = cfb_fillrect,
1660  .fb_copyarea = cfb_copyarea,
1661  .fb_imageblit = cfb_imageblit,
1662 #endif
1663 };
1664 
1665 /* --------------------------------------------------------------------- */
1666 
1667 static struct fb_var_screeninfo __devinitdata savagefb_var800x600x8 = {
1668  .accel_flags = FB_ACCELF_TEXT,
1669  .xres = 800,
1670  .yres = 600,
1671  .xres_virtual = 800,
1672  .yres_virtual = 600,
1673  .bits_per_pixel = 8,
1674  .pixclock = 25000,
1675  .left_margin = 88,
1676  .right_margin = 40,
1677  .upper_margin = 23,
1678  .lower_margin = 1,
1679  .hsync_len = 128,
1680  .vsync_len = 4,
1682  .vmode = FB_VMODE_NONINTERLACED
1683 };
1684 
1685 static void savage_enable_mmio(struct savagefb_par *par)
1686 {
1687  unsigned char val;
1688 
1689  DBG("savage_enable_mmio\n");
1690 
1691  val = vga_in8(0x3c3, par);
1692  vga_out8(0x3c3, val | 0x01, par);
1693  val = vga_in8(0x3cc, par);
1694  vga_out8(0x3c2, val | 0x01, par);
1695 
1696  if (par->chip >= S3_SAVAGE4) {
1697  vga_out8(0x3d4, 0x40, par);
1698  val = vga_in8(0x3d5, par);
1699  vga_out8(0x3d5, val | 1, par);
1700  }
1701 }
1702 
1703 
1704 static void savage_disable_mmio(struct savagefb_par *par)
1705 {
1706  unsigned char val;
1707 
1708  DBG("savage_disable_mmio\n");
1709 
1710  if (par->chip >= S3_SAVAGE4) {
1711  vga_out8(0x3d4, 0x40, par);
1712  val = vga_in8(0x3d5, par);
1713  vga_out8(0x3d5, val | 1, par);
1714  }
1715 }
1716 
1717 
1718 static int __devinit savage_map_mmio(struct fb_info *info)
1719 {
1720  struct savagefb_par *par = info->par;
1721  DBG("savage_map_mmio");
1722 
1723  if (S3_SAVAGE3D_SERIES(par->chip))
1724  par->mmio.pbase = pci_resource_start(par->pcidev, 0) +
1726  else
1727  par->mmio.pbase = pci_resource_start(par->pcidev, 0) +
1729 
1730  par->mmio.len = SAVAGE_NEWMMIO_REGSIZE;
1731 
1732  par->mmio.vbase = ioremap(par->mmio.pbase, par->mmio.len);
1733  if (!par->mmio.vbase) {
1734  printk("savagefb: unable to map memory mapped IO\n");
1735  return -ENOMEM;
1736  } else
1737  printk(KERN_INFO "savagefb: mapped io at %p\n",
1738  par->mmio.vbase);
1739 
1740  info->fix.mmio_start = par->mmio.pbase;
1741  info->fix.mmio_len = par->mmio.len;
1742 
1743  par->bci_base = (u32 __iomem *)(par->mmio.vbase + BCI_BUFFER_OFFSET);
1744  par->bci_ptr = 0;
1745 
1746  savage_enable_mmio(par);
1747 
1748  return 0;
1749 }
1750 
1751 static void savage_unmap_mmio(struct fb_info *info)
1752 {
1753  struct savagefb_par *par = info->par;
1754  DBG("savage_unmap_mmio");
1755 
1756  savage_disable_mmio(par);
1757 
1758  if (par->mmio.vbase) {
1759  iounmap(par->mmio.vbase);
1760  par->mmio.vbase = NULL;
1761  }
1762 }
1763 
1764 static int __devinit savage_map_video(struct fb_info *info,
1765  int video_len)
1766 {
1767  struct savagefb_par *par = info->par;
1768  int resource;
1769 
1770  DBG("savage_map_video");
1771 
1772  if (S3_SAVAGE3D_SERIES(par->chip))
1773  resource = 0;
1774  else
1775  resource = 1;
1776 
1777  par->video.pbase = pci_resource_start(par->pcidev, resource);
1778  par->video.len = video_len;
1779  par->video.vbase = ioremap(par->video.pbase, par->video.len);
1780 
1781  if (!par->video.vbase) {
1782  printk("savagefb: unable to map screen memory\n");
1783  return -ENOMEM;
1784  } else
1785  printk(KERN_INFO "savagefb: mapped framebuffer at %p, "
1786  "pbase == %x\n", par->video.vbase, par->video.pbase);
1787 
1788  info->fix.smem_start = par->video.pbase;
1789  info->fix.smem_len = par->video.len - par->cob_size;
1790  info->screen_base = par->video.vbase;
1791 
1792 #ifdef CONFIG_MTRR
1793  par->video.mtrr = mtrr_add(par->video.pbase, video_len,
1794  MTRR_TYPE_WRCOMB, 1);
1795 #endif
1796 
1797  /* Clear framebuffer, it's all white in memory after boot */
1798  memset_io(par->video.vbase, 0, par->video.len);
1799 
1800  return 0;
1801 }
1802 
1803 static void savage_unmap_video(struct fb_info *info)
1804 {
1805  struct savagefb_par *par = info->par;
1806 
1807  DBG("savage_unmap_video");
1808 
1809  if (par->video.vbase) {
1810 #ifdef CONFIG_MTRR
1811  mtrr_del(par->video.mtrr, par->video.pbase, par->video.len);
1812 #endif
1813 
1814  iounmap(par->video.vbase);
1815  par->video.vbase = NULL;
1816  info->screen_base = NULL;
1817  }
1818 }
1819 
1820 static int savage_init_hw(struct savagefb_par *par)
1821 {
1822  unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp;
1823 
1824  static unsigned char RamSavage3D[] = { 8, 4, 4, 2 };
1825  static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
1826  static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
1827  static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 2, 2 };
1828  int videoRam, videoRambytes, dvi;
1829 
1830  DBG("savage_init_hw");
1831 
1832  /* unprotect CRTC[0-7] */
1833  vga_out8(0x3d4, 0x11, par);
1834  tmp = vga_in8(0x3d5, par);
1835  vga_out8(0x3d5, tmp & 0x7f, par);
1836 
1837  /* unlock extended regs */
1838  vga_out16(0x3d4, 0x4838, par);
1839  vga_out16(0x3d4, 0xa039, par);
1840  vga_out16(0x3c4, 0x0608, par);
1841 
1842  vga_out8(0x3d4, 0x40, par);
1843  tmp = vga_in8(0x3d5, par);
1844  vga_out8(0x3d5, tmp & ~0x01, par);
1845 
1846  /* unlock sys regs */
1847  vga_out8(0x3d4, 0x38, par);
1848  vga_out8(0x3d5, 0x48, par);
1849 
1850  /* Unlock system registers. */
1851  vga_out16(0x3d4, 0x4838, par);
1852 
1853  /* Next go on to detect amount of installed ram */
1854 
1855  vga_out8(0x3d4, 0x36, par); /* for register CR36 (CONFG_REG1), */
1856  config1 = vga_in8(0x3d5, par); /* get amount of vram installed */
1857 
1858  /* Compute the amount of video memory and offscreen memory. */
1859 
1860  switch (par->chip) {
1861  case S3_SAVAGE3D:
1862  videoRam = RamSavage3D[(config1 & 0xC0) >> 6 ] * 1024;
1863  break;
1864 
1865  case S3_SAVAGE4:
1866  /*
1867  * The Savage4 has one ugly special case to consider. On
1868  * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB
1869  * when it really means 8MB. Why do it the same when you
1870  * can do it different...
1871  */
1872  vga_out8(0x3d4, 0x68, par); /* memory control 1 */
1873  if ((vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6))
1874  RamSavage4[1] = 8;
1875 
1876  /*FALLTHROUGH*/
1877 
1878  case S3_SAVAGE2000:
1879  videoRam = RamSavage4[(config1 & 0xE0) >> 5] * 1024;
1880  break;
1881 
1882  case S3_SAVAGE_MX:
1883  case S3_SUPERSAVAGE:
1884  videoRam = RamSavageMX[(config1 & 0x0E) >> 1] * 1024;
1885  break;
1886 
1887  case S3_PROSAVAGE:
1888  case S3_PROSAVAGEDDR:
1889  case S3_TWISTER:
1890  videoRam = RamSavageNB[(config1 & 0xE0) >> 5] * 1024;
1891  break;
1892 
1893  default:
1894  /* How did we get here? */
1895  videoRam = 0;
1896  break;
1897  }
1898 
1899  videoRambytes = videoRam * 1024;
1900 
1901  printk(KERN_INFO "savagefb: probed videoram: %dk\n", videoRam);
1902 
1903  /* reset graphics engine to avoid memory corruption */
1904  vga_out8(0x3d4, 0x66, par);
1905  cr66 = vga_in8(0x3d5, par);
1906  vga_out8(0x3d5, cr66 | 0x02, par);
1907  mdelay(10);
1908 
1909  vga_out8(0x3d4, 0x66, par);
1910  vga_out8(0x3d5, cr66 & ~0x02, par); /* clear reset flag */
1911  mdelay(10);
1912 
1913 
1914  /*
1915  * reset memory interface, 3D engine, AGP master, PCI master,
1916  * master engine unit, motion compensation/LPB
1917  */
1918  vga_out8(0x3d4, 0x3f, par);
1919  cr3f = vga_in8(0x3d5, par);
1920  vga_out8(0x3d5, cr3f | 0x08, par);
1921  mdelay(10);
1922 
1923  vga_out8(0x3d4, 0x3f, par);
1924  vga_out8(0x3d5, cr3f & ~0x08, par); /* clear reset flags */
1925  mdelay(10);
1926 
1927  /* Savage ramdac speeds */
1928  par->numClocks = 4;
1929  par->clock[0] = 250000;
1930  par->clock[1] = 250000;
1931  par->clock[2] = 220000;
1932  par->clock[3] = 220000;
1933 
1934  /* detect current mclk */
1935  vga_out8(0x3c4, 0x08, par);
1936  sr8 = vga_in8(0x3c5, par);
1937  vga_out8(0x3c5, 0x06, par);
1938  vga_out8(0x3c4, 0x10, par);
1939  n = vga_in8(0x3c5, par);
1940  vga_out8(0x3c4, 0x11, par);
1941  m = vga_in8(0x3c5, par);
1942  vga_out8(0x3c4, 0x08, par);
1943  vga_out8(0x3c5, sr8, par);
1944  m &= 0x7f;
1945  n1 = n & 0x1f;
1946  n2 = (n >> 5) & 0x03;
1947  par->MCLK = ((1431818 * (m+2)) / (n1+2) / (1 << n2) + 50) / 100;
1948  printk(KERN_INFO "savagefb: Detected current MCLK value of %d kHz\n",
1949  par->MCLK);
1950 
1951  /* check for DVI/flat panel */
1952  dvi = 0;
1953 
1954  if (par->chip == S3_SAVAGE4) {
1955  unsigned char sr30 = 0x00;
1956 
1957  vga_out8(0x3c4, 0x30, par);
1958  /* clear bit 1 */
1959  vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x02, par);
1960  sr30 = vga_in8(0x3c5, par);
1961  if (sr30 & 0x02 /*0x04 */) {
1962  dvi = 1;
1963  printk("savagefb: Digital Flat Panel Detected\n");
1964  }
1965  }
1966 
1967  if ((S3_SAVAGE_MOBILE_SERIES(par->chip) ||
1968  S3_MOBILE_TWISTER_SERIES(par->chip)) && !par->crtonly)
1969  par->display_type = DISP_LCD;
1970  else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi))
1971  par->display_type = DISP_DFP;
1972  else
1973  par->display_type = DISP_CRT;
1974 
1975  /* Check LCD panel parrmation */
1976 
1977  if (par->display_type == DISP_LCD) {
1978  unsigned char cr6b = VGArCR(0x6b, par);
1979 
1980  int panelX = (VGArSEQ(0x61, par) +
1981  ((VGArSEQ(0x66, par) & 0x02) << 7) + 1) * 8;
1982  int panelY = (VGArSEQ(0x69, par) +
1983  ((VGArSEQ(0x6e, par) & 0x70) << 4) + 1);
1984 
1985  char * sTechnology = "Unknown";
1986 
1987  /* OK, I admit it. I don't know how to limit the max dot clock
1988  * for LCD panels of various sizes. I thought I copied the
1989  * formula from the BIOS, but many users have parrmed me of
1990  * my folly.
1991  *
1992  * Instead, I'll abandon any attempt to automatically limit the
1993  * clock, and add an LCDClock option to XF86Config. Some day,
1994  * I should come back to this.
1995  */
1996 
1997  enum ACTIVE_DISPLAYS { /* These are the bits in CR6B */
1998  ActiveCRT = 0x01,
1999  ActiveLCD = 0x02,
2000  ActiveTV = 0x04,
2001  ActiveCRT2 = 0x20,
2002  ActiveDUO = 0x80
2003  };
2004 
2005  if ((VGArSEQ(0x39, par) & 0x03) == 0) {
2006  sTechnology = "TFT";
2007  } else if ((VGArSEQ(0x30, par) & 0x01) == 0) {
2008  sTechnology = "DSTN";
2009  } else {
2010  sTechnology = "STN";
2011  }
2012 
2013  printk(KERN_INFO "savagefb: %dx%d %s LCD panel detected %s\n",
2014  panelX, panelY, sTechnology,
2015  cr6b & ActiveLCD ? "and active" : "but not active");
2016 
2017  if (cr6b & ActiveLCD) {
2018  /*
2019  * If the LCD is active and panel expansion is enabled,
2020  * we probably want to kill the HW cursor.
2021  */
2022 
2023  printk(KERN_INFO "savagefb: Limiting video mode to "
2024  "%dx%d\n", panelX, panelY);
2025 
2026  par->SavagePanelWidth = panelX;
2027  par->SavagePanelHeight = panelY;
2028 
2029  } else
2030  par->display_type = DISP_CRT;
2031  }
2032 
2033  savage_get_default_par(par, &par->state);
2034  par->save = par->state;
2035 
2036  if (S3_SAVAGE4_SERIES(par->chip)) {
2037  /*
2038  * The Savage4 and ProSavage have COB coherency bugs which
2039  * render the buffer useless. We disable it.
2040  */
2041  par->cob_index = 2;
2042  par->cob_size = 0x8000 << par->cob_index;
2043  par->cob_offset = videoRambytes;
2044  } else {
2045  /* We use 128kB for the COB on all chips. */
2046 
2047  par->cob_index = 7;
2048  par->cob_size = 0x400 << par->cob_index;
2049  par->cob_offset = videoRambytes - par->cob_size;
2050  }
2051 
2052  return videoRambytes;
2053 }
2054 
2055 static int __devinit savage_init_fb_info(struct fb_info *info,
2056  struct pci_dev *dev,
2057  const struct pci_device_id *id)
2058 {
2059  struct savagefb_par *par = info->par;
2060  int err = 0;
2061 
2062  par->pcidev = dev;
2063 
2064  info->fix.type = FB_TYPE_PACKED_PIXELS;
2065  info->fix.type_aux = 0;
2066  info->fix.ypanstep = 1;
2067  info->fix.ywrapstep = 0;
2068  info->fix.accel = id->driver_data;
2069 
2070  switch (info->fix.accel) {
2071  case FB_ACCEL_SUPERSAVAGE:
2072  par->chip = S3_SUPERSAVAGE;
2073  snprintf(info->fix.id, 16, "SuperSavage");
2074  break;
2075  case FB_ACCEL_SAVAGE4:
2076  par->chip = S3_SAVAGE4;
2077  snprintf(info->fix.id, 16, "Savage4");
2078  break;
2079  case FB_ACCEL_SAVAGE3D:
2080  par->chip = S3_SAVAGE3D;
2081  snprintf(info->fix.id, 16, "Savage3D");
2082  break;
2083  case FB_ACCEL_SAVAGE3D_MV:
2084  par->chip = S3_SAVAGE3D;
2085  snprintf(info->fix.id, 16, "Savage3D-MV");
2086  break;
2087  case FB_ACCEL_SAVAGE2000:
2088  par->chip = S3_SAVAGE2000;
2089  snprintf(info->fix.id, 16, "Savage2000");
2090  break;
2091  case FB_ACCEL_SAVAGE_MX_MV:
2092  par->chip = S3_SAVAGE_MX;
2093  snprintf(info->fix.id, 16, "Savage/MX-MV");
2094  break;
2095  case FB_ACCEL_SAVAGE_MX:
2096  par->chip = S3_SAVAGE_MX;
2097  snprintf(info->fix.id, 16, "Savage/MX");
2098  break;
2099  case FB_ACCEL_SAVAGE_IX_MV:
2100  par->chip = S3_SAVAGE_MX;
2101  snprintf(info->fix.id, 16, "Savage/IX-MV");
2102  break;
2103  case FB_ACCEL_SAVAGE_IX:
2104  par->chip = S3_SAVAGE_MX;
2105  snprintf(info->fix.id, 16, "Savage/IX");
2106  break;
2107  case FB_ACCEL_PROSAVAGE_PM:
2108  par->chip = S3_PROSAVAGE;
2109  snprintf(info->fix.id, 16, "ProSavagePM");
2110  break;
2111  case FB_ACCEL_PROSAVAGE_KM:
2112  par->chip = S3_PROSAVAGE;
2113  snprintf(info->fix.id, 16, "ProSavageKM");
2114  break;
2115  case FB_ACCEL_S3TWISTER_P:
2116  par->chip = S3_TWISTER;
2117  snprintf(info->fix.id, 16, "TwisterP");
2118  break;
2119  case FB_ACCEL_S3TWISTER_K:
2120  par->chip = S3_TWISTER;
2121  snprintf(info->fix.id, 16, "TwisterK");
2122  break;
2124  par->chip = S3_PROSAVAGEDDR;
2125  snprintf(info->fix.id, 16, "ProSavageDDR");
2126  break;
2128  par->chip = S3_PROSAVAGEDDR;
2129  snprintf(info->fix.id, 16, "ProSavage8");
2130  break;
2131  }
2132 
2133  if (S3_SAVAGE3D_SERIES(par->chip)) {
2134  par->SavageWaitIdle = savage3D_waitidle;
2135  par->SavageWaitFifo = savage3D_waitfifo;
2136  } else if (S3_SAVAGE4_SERIES(par->chip) ||
2137  S3_SUPERSAVAGE == par->chip) {
2138  par->SavageWaitIdle = savage4_waitidle;
2139  par->SavageWaitFifo = savage4_waitfifo;
2140  } else {
2141  par->SavageWaitIdle = savage2000_waitidle;
2142  par->SavageWaitFifo = savage2000_waitfifo;
2143  }
2144 
2145  info->var.nonstd = 0;
2146  info->var.activate = FB_ACTIVATE_NOW;
2147  info->var.width = -1;
2148  info->var.height = -1;
2149  info->var.accel_flags = 0;
2150 
2151  info->fbops = &savagefb_ops;
2152  info->flags = FBINFO_DEFAULT |
2155 
2156  info->pseudo_palette = par->pseudo_palette;
2157 
2158 #if defined(CONFIG_FB_SAVAGE_ACCEL)
2159  /* FIFO size + padding for commands */
2160  info->pixmap.addr = kcalloc(8, 1024, GFP_KERNEL);
2161 
2162  err = -ENOMEM;
2163  if (info->pixmap.addr) {
2164  info->pixmap.size = 8*1024;
2165  info->pixmap.scan_align = 4;
2166  info->pixmap.buf_align = 4;
2167  info->pixmap.access_align = 32;
2168 
2169  err = fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
2170  if (!err)
2171  info->flags |= FBINFO_HWACCEL_COPYAREA |
2174  }
2175 #endif
2176  return err;
2177 }
2178 
2179 /* --------------------------------------------------------------------- */
2180 
2181 static int __devinit savagefb_probe(struct pci_dev* dev,
2182  const struct pci_device_id* id)
2183 {
2184  struct fb_info *info;
2185  struct savagefb_par *par;
2186  u_int h_sync, v_sync;
2187  int err, lpitch;
2188  int video_len;
2189 
2190  DBG("savagefb_probe");
2191 
2192  info = framebuffer_alloc(sizeof(struct savagefb_par), &dev->dev);
2193  if (!info)
2194  return -ENOMEM;
2195  par = info->par;
2196  mutex_init(&par->open_lock);
2197  err = pci_enable_device(dev);
2198  if (err)
2199  goto failed_enable;
2200 
2201  if ((err = pci_request_regions(dev, "savagefb"))) {
2202  printk(KERN_ERR "cannot request PCI regions\n");
2203  goto failed_enable;
2204  }
2205 
2206  err = -ENOMEM;
2207 
2208  if ((err = savage_init_fb_info(info, dev, id)))
2209  goto failed_init;
2210 
2211  err = savage_map_mmio(info);
2212  if (err)
2213  goto failed_mmio;
2214 
2215  video_len = savage_init_hw(par);
2216  /* FIXME: can't be negative */
2217  if (video_len < 0) {
2218  err = video_len;
2219  goto failed_mmio;
2220  }
2221 
2222  err = savage_map_video(info, video_len);
2223  if (err)
2224  goto failed_video;
2225 
2226  INIT_LIST_HEAD(&info->modelist);
2227 #if defined(CONFIG_FB_SAVAGE_I2C)
2229  savagefb_probe_i2c_connector(info, &par->edid);
2230  fb_edid_to_monspecs(par->edid, &info->monspecs);
2231  kfree(par->edid);
2232  fb_videomode_to_modelist(info->monspecs.modedb,
2233  info->monspecs.modedb_len,
2234  &info->modelist);
2235 #endif
2236  info->var = savagefb_var800x600x8;
2237  /* if a panel was detected, default to a CVT mode instead */
2238  if (par->SavagePanelWidth) {
2239  struct fb_videomode cvt_mode;
2240 
2241  memset(&cvt_mode, 0, sizeof(cvt_mode));
2242  cvt_mode.xres = par->SavagePanelWidth;
2243  cvt_mode.yres = par->SavagePanelHeight;
2244  cvt_mode.refresh = 60;
2245  /* FIXME: if we know there is only the panel
2246  * we can enable reduced blanking as well */
2247  if (fb_find_mode_cvt(&cvt_mode, 0, 0))
2248  printk(KERN_WARNING "No CVT mode found for panel\n");
2249  else if (fb_find_mode(&info->var, info, NULL, NULL, 0,
2250  &cvt_mode, 0) != 3)
2251  info->var = savagefb_var800x600x8;
2252  }
2253 
2254  if (mode_option) {
2255  fb_find_mode(&info->var, info, mode_option,
2256  info->monspecs.modedb, info->monspecs.modedb_len,
2257  NULL, 8);
2258  } else if (info->monspecs.modedb != NULL) {
2259  const struct fb_videomode *mode;
2260 
2261  mode = fb_find_best_display(&info->monspecs, &info->modelist);
2262  savage_update_var(&info->var, mode);
2263  }
2264 
2265  /* maximize virtual vertical length */
2266  lpitch = info->var.xres_virtual*((info->var.bits_per_pixel + 7) >> 3);
2267  info->var.yres_virtual = info->fix.smem_len/lpitch;
2268 
2269  if (info->var.yres_virtual < info->var.yres) {
2270  err = -ENOMEM;
2271  goto failed;
2272  }
2273 
2274 #if defined(CONFIG_FB_SAVAGE_ACCEL)
2275  /*
2276  * The clipping coordinates are masked with 0xFFF, so limit our
2277  * virtual resolutions to these sizes.
2278  */
2279  if (info->var.yres_virtual > 0x1000)
2280  info->var.yres_virtual = 0x1000;
2281 
2282  if (info->var.xres_virtual > 0x1000)
2283  info->var.xres_virtual = 0x1000;
2284 #endif
2285  savagefb_check_var(&info->var, info);
2286  savagefb_set_fix(info);
2287 
2288  /*
2289  * Calculate the hsync and vsync frequencies. Note that
2290  * we split the 1e12 constant up so that we can preserve
2291  * the precision and fit the results into 32-bit registers.
2292  * (1953125000 * 512 = 1e12)
2293  */
2294  h_sync = 1953125000 / info->var.pixclock;
2295  h_sync = h_sync * 512 / (info->var.xres + info->var.left_margin +
2296  info->var.right_margin +
2297  info->var.hsync_len);
2298  v_sync = h_sync / (info->var.yres + info->var.upper_margin +
2299  info->var.lower_margin + info->var.vsync_len);
2300 
2301  printk(KERN_INFO "savagefb v" SAVAGEFB_VERSION ": "
2302  "%dkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
2303  info->fix.smem_len >> 10,
2304  info->var.xres, info->var.yres,
2305  h_sync / 1000, h_sync % 1000, v_sync);
2306 
2307 
2308  fb_destroy_modedb(info->monspecs.modedb);
2309  info->monspecs.modedb = NULL;
2310 
2311  err = register_framebuffer(info);
2312  if (err < 0)
2313  goto failed;
2314 
2315  printk(KERN_INFO "fb: S3 %s frame buffer device\n",
2316  info->fix.id);
2317 
2318  /*
2319  * Our driver data
2320  */
2321  pci_set_drvdata(dev, info);
2322 
2323  return 0;
2324 
2325  failed:
2326 #ifdef CONFIG_FB_SAVAGE_I2C
2328 #endif
2329  fb_alloc_cmap(&info->cmap, 0, 0);
2330  savage_unmap_video(info);
2331  failed_video:
2332  savage_unmap_mmio(info);
2333  failed_mmio:
2334  kfree(info->pixmap.addr);
2335  failed_init:
2336  pci_release_regions(dev);
2337  failed_enable:
2338  framebuffer_release(info);
2339 
2340  return err;
2341 }
2342 
2343 static void __devexit savagefb_remove(struct pci_dev *dev)
2344 {
2345  struct fb_info *info = pci_get_drvdata(dev);
2346 
2347  DBG("savagefb_remove");
2348 
2349  if (info) {
2350  /*
2351  * If unregister_framebuffer fails, then
2352  * we will be leaving hooks that could cause
2353  * oopsen laying around.
2354  */
2355  if (unregister_framebuffer(info))
2356  printk(KERN_WARNING "savagefb: danger danger! "
2357  "Oopsen imminent!\n");
2358 
2359 #ifdef CONFIG_FB_SAVAGE_I2C
2361 #endif
2362  fb_alloc_cmap(&info->cmap, 0, 0);
2363  savage_unmap_video(info);
2364  savage_unmap_mmio(info);
2365  kfree(info->pixmap.addr);
2366  pci_release_regions(dev);
2367  framebuffer_release(info);
2368 
2369  /*
2370  * Ensure that the driver data is no longer
2371  * valid.
2372  */
2373  pci_set_drvdata(dev, NULL);
2374  }
2375 }
2376 
2377 static int savagefb_suspend(struct pci_dev *dev, pm_message_t mesg)
2378 {
2379  struct fb_info *info = pci_get_drvdata(dev);
2380  struct savagefb_par *par = info->par;
2381 
2382  DBG("savagefb_suspend");
2383 
2384  if (mesg.event == PM_EVENT_PRETHAW)
2385  mesg.event = PM_EVENT_FREEZE;
2386  par->pm_state = mesg.event;
2387  dev->dev.power.power_state = mesg;
2388 
2389  /*
2390  * For PM_EVENT_FREEZE, do not power down so the console
2391  * can remain active.
2392  */
2393  if (mesg.event == PM_EVENT_FREEZE)
2394  return 0;
2395 
2396  console_lock();
2397  fb_set_suspend(info, 1);
2398 
2399  if (info->fbops->fb_sync)
2400  info->fbops->fb_sync(info);
2401 
2402  savagefb_blank(FB_BLANK_POWERDOWN, info);
2403  savage_set_default_par(par, &par->save);
2404  savage_disable_mmio(par);
2405  pci_save_state(dev);
2406  pci_disable_device(dev);
2407  pci_set_power_state(dev, pci_choose_state(dev, mesg));
2408  console_unlock();
2409 
2410  return 0;
2411 }
2412 
2413 static int savagefb_resume(struct pci_dev* dev)
2414 {
2415  struct fb_info *info = pci_get_drvdata(dev);
2416  struct savagefb_par *par = info->par;
2417  int cur_state = par->pm_state;
2418 
2419  DBG("savage_resume");
2420 
2421  par->pm_state = PM_EVENT_ON;
2422 
2423  /*
2424  * The adapter was not powered down coming back from a
2425  * PM_EVENT_FREEZE.
2426  */
2427  if (cur_state == PM_EVENT_FREEZE) {
2429  return 0;
2430  }
2431 
2432  console_lock();
2433 
2435  pci_restore_state(dev);
2436 
2437  if (pci_enable_device(dev))
2438  DBG("err");
2439 
2440  pci_set_master(dev);
2441  savage_enable_mmio(par);
2442  savage_init_hw(par);
2443  savagefb_set_par(info);
2444  fb_set_suspend(info, 0);
2445  savagefb_blank(FB_BLANK_UNBLANK, info);
2446  console_unlock();
2447 
2448  return 0;
2449 }
2450 
2451 
2452 static struct pci_device_id savagefb_devices[] __devinitdata = {
2455 
2458 
2461 
2464 
2467 
2470 
2473 
2476 
2479 
2482 
2485 
2488 
2491 
2494 
2497 
2500 
2503 
2506 
2509 
2512 
2515 
2518 
2521 
2522  {0, 0, 0, 0, 0, 0, 0}
2523 };
2524 
2525 MODULE_DEVICE_TABLE(pci, savagefb_devices);
2526 
2527 static struct pci_driver savagefb_driver = {
2528  .name = "savagefb",
2529  .id_table = savagefb_devices,
2530  .probe = savagefb_probe,
2531  .suspend = savagefb_suspend,
2532  .resume = savagefb_resume,
2533  .remove = __devexit_p(savagefb_remove)
2534 };
2535 
2536 /* **************************** exit-time only **************************** */
2537 
2538 static void __exit savage_done(void)
2539 {
2540  DBG("savage_done");
2541  pci_unregister_driver(&savagefb_driver);
2542 }
2543 
2544 
2545 /* ************************* init in-kernel code ************************** */
2546 
2547 static int __init savagefb_setup(char *options)
2548 {
2549 #ifndef MODULE
2550  char *this_opt;
2551 
2552  if (!options || !*options)
2553  return 0;
2554 
2555  while ((this_opt = strsep(&options, ",")) != NULL) {
2556  mode_option = this_opt;
2557  }
2558 #endif /* !MODULE */
2559  return 0;
2560 }
2561 
2562 static int __init savagefb_init(void)
2563 {
2564  char *option;
2565 
2566  DBG("savagefb_init");
2567 
2568  if (fb_get_options("savagefb", &option))
2569  return -ENODEV;
2570 
2571  savagefb_setup(option);
2572  return pci_register_driver(&savagefb_driver);
2573 
2574 }
2575 
2576 module_init(savagefb_init);
2577 module_exit(savage_done);
2578 
2579 module_param(mode_option, charp, 0);
2580 MODULE_PARM_DESC(mode_option, "Specify initial video mode");