Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cirrusfb.c
Go to the documentation of this file.
1 /*
2  * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
3  *
4  * Copyright 1999-2001 Jeff Garzik <[email protected]>
5  *
6  * Contributors (thanks, all!)
7  *
8  * David Eger:
9  * Overhaul for Linux 2.6
10  *
11  * Jeff Rugen:
12  * Major contributions; Motorola PowerStack (PPC and PCI) support,
13  * GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
14  *
15  * Geert Uytterhoeven:
16  * Excellent code review.
17  *
18  * Lars Hecking:
19  * Amiga updates and testing.
20  *
21  * Original cirrusfb author: Frank Neumann
22  *
23  * Based on retz3fb.c and cirrusfb.c:
24  * Copyright (C) 1997 Jes Sorensen
25  * Copyright (C) 1996 Frank Neumann
26  *
27  ***************************************************************
28  *
29  * Format this code with GNU indent '-kr -i8 -pcs' options.
30  *
31  * This file is subject to the terms and conditions of the GNU General Public
32  * License. See the file COPYING in the main directory of this archive
33  * for more details.
34  *
35  */
36 
37 #include <linux/module.h>
38 #include <linux/kernel.h>
39 #include <linux/errno.h>
40 #include <linux/string.h>
41 #include <linux/mm.h>
42 #include <linux/delay.h>
43 #include <linux/fb.h>
44 #include <linux/init.h>
45 #include <asm/pgtable.h>
46 
47 #ifdef CONFIG_ZORRO
48 #include <linux/zorro.h>
49 #endif
50 #ifdef CONFIG_PCI
51 #include <linux/pci.h>
52 #endif
53 #ifdef CONFIG_AMIGA
54 #include <asm/amigahw.h>
55 #endif
56 #ifdef CONFIG_PPC_PREP
57 #include <asm/machdep.h>
58 #define isPReP machine_is(prep)
59 #else
60 #define isPReP 0
61 #endif
62 
63 #include <video/vga.h>
64 #include <video/cirrus.h>
65 
66 /*****************************************************************
67  *
68  * debugging and utility macros
69  *
70  */
71 
72 /* disable runtime assertions? */
73 /* #define CIRRUSFB_NDEBUG */
74 
75 /* debugging assertions */
76 #ifndef CIRRUSFB_NDEBUG
77 #define assert(expr) \
78  if (!(expr)) { \
79  printk("Assertion failed! %s,%s,%s,line=%d\n", \
80  #expr, __FILE__, __func__, __LINE__); \
81  }
82 #else
83 #define assert(expr)
84 #endif
85 
86 #define MB_ (1024 * 1024)
87 
88 /*****************************************************************
89  *
90  * chipset information
91  *
92  */
93 
94 /* board types */
96  BT_NONE = 0,
97  BT_SD64, /* GD5434 */
98  BT_PICCOLO, /* GD5426 */
99  BT_PICASSO, /* GD5426 or GD5428 */
100  BT_SPECTRUM, /* GD5426 or GD5428 */
101  BT_PICASSO4, /* GD5446 */
102  BT_ALPINE, /* GD543x/4x */
104  BT_LAGUNA, /* GD5462/64 */
105  BT_LAGUNAB, /* GD5465 */
106 };
107 
108 /*
109  * per-board-type information, used for enumerating and abstracting
110  * chip-specific information
111  * NOTE: MUST be in the same order as enum cirrus_board in order to
112  * use direct indexing on this array
113  * NOTE: '__initdata' cannot be used as some of this info
114  * is required at runtime. Maybe separate into an init-only and
115  * a run-time table?
116  */
117 static const struct cirrusfb_board_info_rec {
118  char *name; /* ASCII name of chipset */
119  long maxclock[5]; /* maximum video clock */
120  /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
121  bool init_sr07 : 1; /* init SR07 during init_vgachip() */
122  bool init_sr1f : 1; /* write SR1F during init_vgachip() */
123  /* construct bit 19 of screen start address */
124  bool scrn_start_bit19 : 1;
125 
126  /* initial SR07 value, then for each mode */
127  unsigned char sr07;
128  unsigned char sr07_1bpp;
129  unsigned char sr07_1bpp_mux;
130  unsigned char sr07_8bpp;
131  unsigned char sr07_8bpp_mux;
132 
133  unsigned char sr1f; /* SR1F VGA initial register value */
134 } cirrusfb_board_info[] = {
135  [BT_SD64] = {
136  .name = "CL SD64",
137  .maxclock = {
138  /* guess */
139  /* the SD64/P4 have a higher max. videoclock */
140  135100, 135100, 85500, 85500, 0
141  },
142  .init_sr07 = true,
143  .init_sr1f = true,
144  .scrn_start_bit19 = true,
145  .sr07 = 0xF0,
146  .sr07_1bpp = 0xF0,
147  .sr07_1bpp_mux = 0xF6,
148  .sr07_8bpp = 0xF1,
149  .sr07_8bpp_mux = 0xF7,
150  .sr1f = 0x1E
151  },
152  [BT_PICCOLO] = {
153  .name = "CL Piccolo",
154  .maxclock = {
155  /* guess */
156  90000, 90000, 90000, 90000, 90000
157  },
158  .init_sr07 = true,
159  .init_sr1f = true,
160  .scrn_start_bit19 = false,
161  .sr07 = 0x80,
162  .sr07_1bpp = 0x80,
163  .sr07_8bpp = 0x81,
164  .sr1f = 0x22
165  },
166  [BT_PICASSO] = {
167  .name = "CL Picasso",
168  .maxclock = {
169  /* guess */
170  90000, 90000, 90000, 90000, 90000
171  },
172  .init_sr07 = true,
173  .init_sr1f = true,
174  .scrn_start_bit19 = false,
175  .sr07 = 0x20,
176  .sr07_1bpp = 0x20,
177  .sr07_8bpp = 0x21,
178  .sr1f = 0x22
179  },
180  [BT_SPECTRUM] = {
181  .name = "CL Spectrum",
182  .maxclock = {
183  /* guess */
184  90000, 90000, 90000, 90000, 90000
185  },
186  .init_sr07 = true,
187  .init_sr1f = true,
188  .scrn_start_bit19 = false,
189  .sr07 = 0x80,
190  .sr07_1bpp = 0x80,
191  .sr07_8bpp = 0x81,
192  .sr1f = 0x22
193  },
194  [BT_PICASSO4] = {
195  .name = "CL Picasso4",
196  .maxclock = {
197  135100, 135100, 85500, 85500, 0
198  },
199  .init_sr07 = true,
200  .init_sr1f = false,
201  .scrn_start_bit19 = true,
202  .sr07 = 0xA0,
203  .sr07_1bpp = 0xA0,
204  .sr07_1bpp_mux = 0xA6,
205  .sr07_8bpp = 0xA1,
206  .sr07_8bpp_mux = 0xA7,
207  .sr1f = 0
208  },
209  [BT_ALPINE] = {
210  .name = "CL Alpine",
211  .maxclock = {
212  /* for the GD5430. GD5446 can do more... */
213  85500, 85500, 50000, 28500, 0
214  },
215  .init_sr07 = true,
216  .init_sr1f = true,
217  .scrn_start_bit19 = true,
218  .sr07 = 0xA0,
219  .sr07_1bpp = 0xA0,
220  .sr07_1bpp_mux = 0xA6,
221  .sr07_8bpp = 0xA1,
222  .sr07_8bpp_mux = 0xA7,
223  .sr1f = 0x1C
224  },
225  [BT_GD5480] = {
226  .name = "CL GD5480",
227  .maxclock = {
228  135100, 200000, 200000, 135100, 135100
229  },
230  .init_sr07 = true,
231  .init_sr1f = true,
232  .scrn_start_bit19 = true,
233  .sr07 = 0x10,
234  .sr07_1bpp = 0x11,
235  .sr07_8bpp = 0x11,
236  .sr1f = 0x1C
237  },
238  [BT_LAGUNA] = {
239  .name = "CL Laguna",
240  .maxclock = {
241  /* taken from X11 code */
242  170000, 170000, 170000, 170000, 135100,
243  },
244  .init_sr07 = false,
245  .init_sr1f = false,
246  .scrn_start_bit19 = true,
247  },
248  [BT_LAGUNAB] = {
249  .name = "CL Laguna AGP",
250  .maxclock = {
251  /* taken from X11 code */
252  170000, 250000, 170000, 170000, 135100,
253  },
254  .init_sr07 = false,
255  .init_sr1f = false,
256  .scrn_start_bit19 = true,
257  }
258 };
259 
260 #ifdef CONFIG_PCI
261 #define CHIP(id, btype) \
262  { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
263 
264 static struct pci_device_id cirrusfb_pci_table[] = {
268  CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
271  CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
272  CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
273  CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
274  CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
275  CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
276  { 0, }
277 };
278 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
279 #undef CHIP
280 #endif /* CONFIG_PCI */
281 
282 #ifdef CONFIG_ZORRO
283 struct zorrocl {
284  enum cirrus_board type; /* Board type */
285  u32 regoffset; /* Offset of registers in first Zorro device */
286  u32 ramsize; /* Size of video RAM in first Zorro device */
287  /* If zero, use autoprobe on RAM device */
288  u32 ramoffset; /* Offset of video RAM in first Zorro device */
289  zorro_id ramid; /* Zorro ID of RAM device */
290  zorro_id ramid2; /* Zorro ID of optional second RAM device */
291 };
292 
293 static const struct zorrocl zcl_sd64 __devinitconst = {
294  .type = BT_SD64,
296 };
297 
298 static const struct zorrocl zcl_piccolo __devinitconst = {
299  .type = BT_PICCOLO,
301 };
302 
303 static const struct zorrocl zcl_picasso __devinitconst = {
304  .type = BT_PICASSO,
306 };
307 
308 static const struct zorrocl zcl_spectrum __devinitconst = {
309  .type = BT_SPECTRUM,
311 };
312 
313 static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
314  .type = BT_PICASSO4,
315  .regoffset = 0x00600000,
316  .ramsize = 4 * MB_,
317  .ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */
318 };
319 
320 static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
321  .type = BT_PICASSO4,
322  .regoffset = 0x10000,
325 };
326 
327 
328 static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
329  {
331  .driver_data = (unsigned long)&zcl_sd64,
332  }, {
334  .driver_data = (unsigned long)&zcl_piccolo,
335  }, {
337  .driver_data = (unsigned long)&zcl_picasso,
338  }, {
340  .driver_data = (unsigned long)&zcl_spectrum,
341  }, {
343  .driver_data = (unsigned long)&zcl_picasso4_z3,
344  }, {
346  .driver_data = (unsigned long)&zcl_picasso4_z2,
347  },
348  { 0 }
349 };
350 MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
351 #endif /* CONFIG_ZORRO */
352 
353 #ifdef CIRRUSFB_DEBUG
354 enum cirrusfb_dbg_reg_class {
355  CRT,
356  SEQ
357 };
358 #endif /* CIRRUSFB_DEBUG */
359 
360 /* info about board */
365  unsigned char SFR; /* Shadow of special function register */
366 
371 
372  void (*unmap)(struct fb_info *info);
373 };
374 
375 static bool noaccel __devinitdata;
376 static char *mode_option __devinitdata = "640x480@60";
377 
378 /****************************************************************************/
379 /**** BEGIN PROTOTYPES ******************************************************/
380 
381 /*--- Interface used by the world ------------------------------------------*/
382 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
383  struct fb_info *info);
384 
385 /*--- Internal routines ----------------------------------------------------*/
386 static void init_vgachip(struct fb_info *info);
387 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
388 static void WGen(const struct cirrusfb_info *cinfo,
389  int regnum, unsigned char val);
390 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
391 static void AttrOn(const struct cirrusfb_info *cinfo);
392 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
393 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
394 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
395 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
396  unsigned char red, unsigned char green, unsigned char blue);
397 #if 0
398 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
399  unsigned char *red, unsigned char *green,
400  unsigned char *blue);
401 #endif
402 static void cirrusfb_WaitBLT(u8 __iomem *regbase);
403 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
404  u_short curx, u_short cury,
405  u_short destx, u_short desty,
407  u_short line_length);
408 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
409  u_short x, u_short y,
411  u32 fg_color, u32 bg_color,
412  u_short line_length, u_char blitmode);
413 
414 static void bestclock(long freq, int *nom, int *den, int *div);
415 
416 #ifdef CIRRUSFB_DEBUG
417 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
418 static void cirrusfb_dbg_print_regs(struct fb_info *info,
419  caddr_t regbase,
420  enum cirrusfb_dbg_reg_class reg_class, ...);
421 #endif /* CIRRUSFB_DEBUG */
422 
423 /*** END PROTOTYPES ********************************************************/
424 /*****************************************************************************/
425 /*** BEGIN Interface Used by the World ***************************************/
426 
427 static inline int is_laguna(const struct cirrusfb_info *cinfo)
428 {
429  return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
430 }
431 
432 static int opencount;
433 
434 /*--- Open /dev/fbx ---------------------------------------------------------*/
435 static int cirrusfb_open(struct fb_info *info, int user)
436 {
437  if (opencount++ == 0)
438  switch_monitor(info->par, 1);
439  return 0;
440 }
441 
442 /*--- Close /dev/fbx --------------------------------------------------------*/
443 static int cirrusfb_release(struct fb_info *info, int user)
444 {
445  if (--opencount == 0)
446  switch_monitor(info->par, 0);
447  return 0;
448 }
449 
450 /**** END Interface used by the World *************************************/
451 /****************************************************************************/
452 /**** BEGIN Hardware specific Routines **************************************/
453 
454 /* Check if the MCLK is not a better clock source */
455 static int cirrusfb_check_mclk(struct fb_info *info, long freq)
456 {
457  struct cirrusfb_info *cinfo = info->par;
458  long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
459 
460  /* Read MCLK value */
461  mclk = (14318 * mclk) >> 3;
462  dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
463 
464  /* Determine if we should use MCLK instead of VCLK, and if so, what we
465  * should divide it by to get VCLK
466  */
467 
468  if (abs(freq - mclk) < 250) {
469  dev_dbg(info->device, "Using VCLK = MCLK\n");
470  return 1;
471  } else if (abs(freq - (mclk / 2)) < 250) {
472  dev_dbg(info->device, "Using VCLK = MCLK/2\n");
473  return 2;
474  }
475 
476  return 0;
477 }
478 
479 static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
480  struct fb_info *info)
481 {
482  long freq;
483  long maxclock;
484  struct cirrusfb_info *cinfo = info->par;
485  unsigned maxclockidx = var->bits_per_pixel >> 3;
486 
487  /* convert from ps to kHz */
488  freq = PICOS2KHZ(var->pixclock);
489 
490  dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
491 
492  maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
493  cinfo->multiplexing = 0;
494 
495  /* If the frequency is greater than we can support, we might be able
496  * to use multiplexing for the video mode */
497  if (freq > maxclock) {
498  dev_err(info->device,
499  "Frequency greater than maxclock (%ld kHz)\n",
500  maxclock);
501  return -EINVAL;
502  }
503  /*
504  * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
505  * pixel clock
506  */
507  if (var->bits_per_pixel == 8) {
508  switch (cinfo->btype) {
509  case BT_ALPINE:
510  case BT_SD64:
511  case BT_PICASSO4:
512  if (freq > 85500)
513  cinfo->multiplexing = 1;
514  break;
515  case BT_GD5480:
516  if (freq > 135100)
517  cinfo->multiplexing = 1;
518  break;
519 
520  default:
521  break;
522  }
523  }
524 
525  /* If we have a 1MB 5434, we need to put ourselves in a mode where
526  * the VCLK is double the pixel clock. */
527  cinfo->doubleVCLK = 0;
528  if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
529  var->bits_per_pixel == 16) {
530  cinfo->doubleVCLK = 1;
531  }
532 
533  return 0;
534 }
535 
536 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
537  struct fb_info *info)
538 {
539  int yres;
540  /* memory size in pixels */
541  unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
542  struct cirrusfb_info *cinfo = info->par;
543 
544  switch (var->bits_per_pixel) {
545  case 1:
546  var->red.offset = 0;
547  var->red.length = 1;
548  var->green = var->red;
549  var->blue = var->red;
550  break;
551 
552  case 8:
553  var->red.offset = 0;
554  var->red.length = 8;
555  var->green = var->red;
556  var->blue = var->red;
557  break;
558 
559  case 16:
560  if (isPReP) {
561  var->red.offset = 2;
562  var->green.offset = -3;
563  var->blue.offset = 8;
564  } else {
565  var->red.offset = 11;
566  var->green.offset = 5;
567  var->blue.offset = 0;
568  }
569  var->red.length = 5;
570  var->green.length = 6;
571  var->blue.length = 5;
572  break;
573 
574  case 24:
575  if (isPReP) {
576  var->red.offset = 0;
577  var->green.offset = 8;
578  var->blue.offset = 16;
579  } else {
580  var->red.offset = 16;
581  var->green.offset = 8;
582  var->blue.offset = 0;
583  }
584  var->red.length = 8;
585  var->green.length = 8;
586  var->blue.length = 8;
587  break;
588 
589  default:
590  dev_dbg(info->device,
591  "Unsupported bpp size: %d\n", var->bits_per_pixel);
592  return -EINVAL;
593  }
594 
595  if (var->xres_virtual < var->xres)
596  var->xres_virtual = var->xres;
597  /* use highest possible virtual resolution */
598  if (var->yres_virtual == -1) {
599  var->yres_virtual = pixels / var->xres_virtual;
600 
601  dev_info(info->device,
602  "virtual resolution set to maximum of %dx%d\n",
603  var->xres_virtual, var->yres_virtual);
604  }
605  if (var->yres_virtual < var->yres)
606  var->yres_virtual = var->yres;
607 
608  if (var->xres_virtual * var->yres_virtual > pixels) {
609  dev_err(info->device, "mode %dx%dx%d rejected... "
610  "virtual resolution too high to fit into video memory!\n",
611  var->xres_virtual, var->yres_virtual,
612  var->bits_per_pixel);
613  return -EINVAL;
614  }
615 
616  if (var->xoffset < 0)
617  var->xoffset = 0;
618  if (var->yoffset < 0)
619  var->yoffset = 0;
620 
621  /* truncate xoffset and yoffset to maximum if too high */
622  if (var->xoffset > var->xres_virtual - var->xres)
623  var->xoffset = var->xres_virtual - var->xres - 1;
624  if (var->yoffset > var->yres_virtual - var->yres)
625  var->yoffset = var->yres_virtual - var->yres - 1;
626 
627  var->red.msb_right =
628  var->green.msb_right =
629  var->blue.msb_right =
630  var->transp.offset =
631  var->transp.length =
632  var->transp.msb_right = 0;
633 
634  yres = var->yres;
635  if (var->vmode & FB_VMODE_DOUBLE)
636  yres *= 2;
637  else if (var->vmode & FB_VMODE_INTERLACED)
638  yres = (yres + 1) / 2;
639 
640  if (yres >= 1280) {
641  dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
642  "special treatment required! (TODO)\n");
643  return -EINVAL;
644  }
645 
646  if (cirrusfb_check_pixclock(var, info))
647  return -EINVAL;
648 
649  if (!is_laguna(cinfo))
651 
652  return 0;
653 }
654 
655 static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
656 {
657  struct cirrusfb_info *cinfo = info->par;
658  unsigned char old1f, old1e;
659 
660  assert(cinfo != NULL);
661  old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
662 
663  if (div) {
664  dev_dbg(info->device, "Set %s as pixclock source.\n",
665  (div == 2) ? "MCLK/2" : "MCLK");
666  old1f |= 0x40;
667  old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
668  if (div == 2)
669  old1e |= 1;
670 
671  vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
672  }
673  vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
674 }
675 
676 /*************************************************************************
677  cirrusfb_set_par_foo()
678 
679  actually writes the values for a new video mode into the hardware,
680 **************************************************************************/
681 static int cirrusfb_set_par_foo(struct fb_info *info)
682 {
683  struct cirrusfb_info *cinfo = info->par;
684  struct fb_var_screeninfo *var = &info->var;
685  u8 __iomem *regbase = cinfo->regbase;
686  unsigned char tmp;
687  int pitch;
688  const struct cirrusfb_board_info_rec *bi;
689  int hdispend, hsyncstart, hsyncend, htotal;
690  int yres, vdispend, vsyncstart, vsyncend, vtotal;
691  long freq;
692  int nom, den, div;
693  unsigned int control = 0, format = 0, threshold = 0;
694 
695  dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
696  var->xres, var->yres, var->bits_per_pixel);
697 
698  switch (var->bits_per_pixel) {
699  case 1:
700  info->fix.line_length = var->xres_virtual / 8;
701  info->fix.visual = FB_VISUAL_MONO10;
702  break;
703 
704  case 8:
705  info->fix.line_length = var->xres_virtual;
706  info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
707  break;
708 
709  case 16:
710  case 24:
711  info->fix.line_length = var->xres_virtual *
712  var->bits_per_pixel >> 3;
713  info->fix.visual = FB_VISUAL_TRUECOLOR;
714  break;
715  }
716  info->fix.type = FB_TYPE_PACKED_PIXELS;
717 
718  init_vgachip(info);
719 
720  bi = &cirrusfb_board_info[cinfo->btype];
721 
722  hsyncstart = var->xres + var->right_margin;
723  hsyncend = hsyncstart + var->hsync_len;
724  htotal = (hsyncend + var->left_margin) / 8;
725  hdispend = var->xres / 8;
726  hsyncstart = hsyncstart / 8;
727  hsyncend = hsyncend / 8;
728 
729  vdispend = var->yres;
730  vsyncstart = vdispend + var->lower_margin;
731  vsyncend = vsyncstart + var->vsync_len;
732  vtotal = vsyncend + var->upper_margin;
733 
734  if (var->vmode & FB_VMODE_DOUBLE) {
735  vdispend *= 2;
736  vsyncstart *= 2;
737  vsyncend *= 2;
738  vtotal *= 2;
739  } else if (var->vmode & FB_VMODE_INTERLACED) {
740  vdispend = (vdispend + 1) / 2;
741  vsyncstart = (vsyncstart + 1) / 2;
742  vsyncend = (vsyncend + 1) / 2;
743  vtotal = (vtotal + 1) / 2;
744  }
745  yres = vdispend;
746  if (yres >= 1024) {
747  vtotal /= 2;
748  vsyncstart /= 2;
749  vsyncend /= 2;
750  vdispend /= 2;
751  }
752 
753  vdispend -= 1;
754  vsyncstart -= 1;
755  vsyncend -= 1;
756  vtotal -= 2;
757 
758  if (cinfo->multiplexing) {
759  htotal /= 2;
760  hsyncstart /= 2;
761  hsyncend /= 2;
762  hdispend /= 2;
763  }
764 
765  htotal -= 5;
766  hdispend -= 1;
767  hsyncstart += 1;
768  hsyncend += 1;
769 
770  /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
771  vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
772 
773  /* if debugging is enabled, all parameters get output before writing */
774  dev_dbg(info->device, "CRT0: %d\n", htotal);
775  vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
776 
777  dev_dbg(info->device, "CRT1: %d\n", hdispend);
778  vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
779 
780  dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
781  vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
782 
783  /* + 128: Compatible read */
784  dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
785  vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
786  128 + ((htotal + 5) % 32));
787 
788  dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
789  vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
790 
791  tmp = hsyncend % 32;
792  if ((htotal + 5) & 32)
793  tmp += 128;
794  dev_dbg(info->device, "CRT5: %d\n", tmp);
795  vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
796 
797  dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
798  vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
799 
800  tmp = 16; /* LineCompare bit #9 */
801  if (vtotal & 256)
802  tmp |= 1;
803  if (vdispend & 256)
804  tmp |= 2;
805  if (vsyncstart & 256)
806  tmp |= 4;
807  if ((vdispend + 1) & 256)
808  tmp |= 8;
809  if (vtotal & 512)
810  tmp |= 32;
811  if (vdispend & 512)
812  tmp |= 64;
813  if (vsyncstart & 512)
814  tmp |= 128;
815  dev_dbg(info->device, "CRT7: %d\n", tmp);
816  vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
817 
818  tmp = 0x40; /* LineCompare bit #8 */
819  if ((vdispend + 1) & 512)
820  tmp |= 0x20;
821  if (var->vmode & FB_VMODE_DOUBLE)
822  tmp |= 0x80;
823  dev_dbg(info->device, "CRT9: %d\n", tmp);
824  vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
825 
826  dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
827  vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
828 
829  dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
830  vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
831 
832  dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
833  vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
834 
835  dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
836  vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
837 
838  dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
839  vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
840 
841  dev_dbg(info->device, "CRT18: 0xff\n");
842  vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
843 
844  tmp = 0;
845  if (var->vmode & FB_VMODE_INTERLACED)
846  tmp |= 1;
847  if ((htotal + 5) & 64)
848  tmp |= 16;
849  if ((htotal + 5) & 128)
850  tmp |= 32;
851  if (vtotal & 256)
852  tmp |= 64;
853  if (vtotal & 512)
854  tmp |= 128;
855 
856  dev_dbg(info->device, "CRT1a: %d\n", tmp);
857  vga_wcrt(regbase, CL_CRT1A, tmp);
858 
859  freq = PICOS2KHZ(var->pixclock);
860  if (var->bits_per_pixel == 24)
861  if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
862  freq *= 3;
863  if (cinfo->multiplexing)
864  freq /= 2;
865  if (cinfo->doubleVCLK)
866  freq *= 2;
867 
868  bestclock(freq, &nom, &den, &div);
869 
870  dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n",
871  freq, nom, den, div);
872 
873  /* set VCLK0 */
874  /* hardware RefClock: 14.31818 MHz */
875  /* formula: VClk = (OSC * N) / (D * (1+P)) */
876  /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
877 
878  if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
879  cinfo->btype == BT_SD64) {
880  /* if freq is close to mclk or mclk/2 select mclk
881  * as clock source
882  */
883  int divMCLK = cirrusfb_check_mclk(info, freq);
884  if (divMCLK)
885  nom = 0;
886  cirrusfb_set_mclk_as_source(info, divMCLK);
887  }
888  if (is_laguna(cinfo)) {
889  long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
890  unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
891  unsigned short tile_control;
892 
893  if (cinfo->btype == BT_LAGUNAB) {
894  tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
895  tile_control &= ~0x80;
896  fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
897  }
898 
899  fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
900  fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
901  control = fb_readw(cinfo->laguna_mmio + 0x402);
902  threshold = fb_readw(cinfo->laguna_mmio + 0xea);
903  control &= ~0x6800;
904  format = 0;
905  threshold &= 0xffc0 & 0x3fbf;
906  }
907  if (nom) {
908  tmp = den << 1;
909  if (div != 0)
910  tmp |= 1;
911  /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
912  if ((cinfo->btype == BT_SD64) ||
913  (cinfo->btype == BT_ALPINE) ||
914  (cinfo->btype == BT_GD5480))
915  tmp |= 0x80;
916 
917  /* Laguna chipset has reversed clock registers */
918  if (is_laguna(cinfo)) {
919  vga_wseq(regbase, CL_SEQRE, tmp);
920  vga_wseq(regbase, CL_SEQR1E, nom);
921  } else {
922  vga_wseq(regbase, CL_SEQRE, nom);
923  vga_wseq(regbase, CL_SEQR1E, tmp);
924  }
925  }
926 
927  if (yres >= 1024)
928  /* 1280x1024 */
929  vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
930  else
931  /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
932  * address wrap, no compat. */
933  vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
934 
935  /* don't know if it would hurt to also program this if no interlaced */
936  /* mode is used, but I feel better this way.. :-) */
937  if (var->vmode & FB_VMODE_INTERLACED)
938  vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
939  else
940  vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
941 
942  /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
943  /* enable display memory & CRTC I/O address for color mode */
944  tmp = 0x03 | 0xc;
945  if (var->sync & FB_SYNC_HOR_HIGH_ACT)
946  tmp |= 0x40;
947  if (var->sync & FB_SYNC_VERT_HIGH_ACT)
948  tmp |= 0x80;
949  WGen(cinfo, VGA_MIS_W, tmp);
950 
951  /* text cursor on and start line */
952  vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
953  /* text cursor end line */
954  vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
955 
956  /******************************************************
957  *
958  * 1 bpp
959  *
960  */
961 
962  /* programming for different color depths */
963  if (var->bits_per_pixel == 1) {
964  dev_dbg(info->device, "preparing for 1 bit deep display\n");
965  vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
966 
967  /* SR07 */
968  switch (cinfo->btype) {
969  case BT_SD64:
970  case BT_PICCOLO:
971  case BT_PICASSO:
972  case BT_SPECTRUM:
973  case BT_PICASSO4:
974  case BT_ALPINE:
975  case BT_GD5480:
976  vga_wseq(regbase, CL_SEQR7,
977  cinfo->multiplexing ?
978  bi->sr07_1bpp_mux : bi->sr07_1bpp);
979  break;
980 
981  case BT_LAGUNA:
982  case BT_LAGUNAB:
983  vga_wseq(regbase, CL_SEQR7,
984  vga_rseq(regbase, CL_SEQR7) & ~0x01);
985  break;
986 
987  default:
988  dev_warn(info->device, "unknown Board\n");
989  break;
990  }
991 
992  /* Extended Sequencer Mode */
993  switch (cinfo->btype) {
994 
995  case BT_PICCOLO:
996  case BT_SPECTRUM:
997  /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
998  vga_wseq(regbase, CL_SEQRF, 0xb0);
999  break;
1000 
1001  case BT_PICASSO:
1002  /* ## vorher d0 avoid FIFO underruns..? */
1003  vga_wseq(regbase, CL_SEQRF, 0xd0);
1004  break;
1005 
1006  case BT_SD64:
1007  case BT_PICASSO4:
1008  case BT_ALPINE:
1009  case BT_GD5480:
1010  case BT_LAGUNA:
1011  case BT_LAGUNAB:
1012  /* do nothing */
1013  break;
1014 
1015  default:
1016  dev_warn(info->device, "unknown Board\n");
1017  break;
1018  }
1019 
1020  /* pixel mask: pass-through for first plane */
1021  WGen(cinfo, VGA_PEL_MSK, 0x01);
1022  if (cinfo->multiplexing)
1023  /* hidden dac reg: 1280x1024 */
1024  WHDR(cinfo, 0x4a);
1025  else
1026  /* hidden dac: nothing */
1027  WHDR(cinfo, 0);
1028  /* memory mode: odd/even, ext. memory */
1029  vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1030  /* plane mask: only write to first plane */
1031  vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1032  }
1033 
1034  /******************************************************
1035  *
1036  * 8 bpp
1037  *
1038  */
1039 
1040  else if (var->bits_per_pixel == 8) {
1041  dev_dbg(info->device, "preparing for 8 bit deep display\n");
1042  switch (cinfo->btype) {
1043  case BT_SD64:
1044  case BT_PICCOLO:
1045  case BT_PICASSO:
1046  case BT_SPECTRUM:
1047  case BT_PICASSO4:
1048  case BT_ALPINE:
1049  case BT_GD5480:
1050  vga_wseq(regbase, CL_SEQR7,
1051  cinfo->multiplexing ?
1052  bi->sr07_8bpp_mux : bi->sr07_8bpp);
1053  break;
1054 
1055  case BT_LAGUNA:
1056  case BT_LAGUNAB:
1057  vga_wseq(regbase, CL_SEQR7,
1058  vga_rseq(regbase, CL_SEQR7) | 0x01);
1059  threshold |= 0x10;
1060  break;
1061 
1062  default:
1063  dev_warn(info->device, "unknown Board\n");
1064  break;
1065  }
1066 
1067  switch (cinfo->btype) {
1068  case BT_PICCOLO:
1069  case BT_PICASSO:
1070  case BT_SPECTRUM:
1071  /* Fast Page-Mode writes */
1072  vga_wseq(regbase, CL_SEQRF, 0xb0);
1073  break;
1074 
1075  case BT_PICASSO4:
1076 #ifdef CONFIG_ZORRO
1077  /* ### INCOMPLETE!! */
1078  vga_wseq(regbase, CL_SEQRF, 0xb8);
1079 #endif
1080  case BT_ALPINE:
1081  case BT_SD64:
1082  case BT_GD5480:
1083  case BT_LAGUNA:
1084  case BT_LAGUNAB:
1085  /* do nothing */
1086  break;
1087 
1088  default:
1089  dev_warn(info->device, "unknown board\n");
1090  break;
1091  }
1092 
1093  /* mode register: 256 color mode */
1094  vga_wgfx(regbase, VGA_GFX_MODE, 64);
1095  if (cinfo->multiplexing)
1096  /* hidden dac reg: 1280x1024 */
1097  WHDR(cinfo, 0x4a);
1098  else
1099  /* hidden dac: nothing */
1100  WHDR(cinfo, 0);
1101  }
1102 
1103  /******************************************************
1104  *
1105  * 16 bpp
1106  *
1107  */
1108 
1109  else if (var->bits_per_pixel == 16) {
1110  dev_dbg(info->device, "preparing for 16 bit deep display\n");
1111  switch (cinfo->btype) {
1112  case BT_PICCOLO:
1113  case BT_SPECTRUM:
1114  vga_wseq(regbase, CL_SEQR7, 0x87);
1115  /* Fast Page-Mode writes */
1116  vga_wseq(regbase, CL_SEQRF, 0xb0);
1117  break;
1118 
1119  case BT_PICASSO:
1120  vga_wseq(regbase, CL_SEQR7, 0x27);
1121  /* Fast Page-Mode writes */
1122  vga_wseq(regbase, CL_SEQRF, 0xb0);
1123  break;
1124 
1125  case BT_SD64:
1126  case BT_PICASSO4:
1127  case BT_ALPINE:
1128  /* Extended Sequencer Mode: 256c col. mode */
1129  vga_wseq(regbase, CL_SEQR7,
1130  cinfo->doubleVCLK ? 0xa3 : 0xa7);
1131  break;
1132 
1133  case BT_GD5480:
1134  vga_wseq(regbase, CL_SEQR7, 0x17);
1135  /* We already set SRF and SR1F */
1136  break;
1137 
1138  case BT_LAGUNA:
1139  case BT_LAGUNAB:
1140  vga_wseq(regbase, CL_SEQR7,
1141  vga_rseq(regbase, CL_SEQR7) & ~0x01);
1142  control |= 0x2000;
1143  format |= 0x1400;
1144  threshold |= 0x10;
1145  break;
1146 
1147  default:
1148  dev_warn(info->device, "unknown Board\n");
1149  break;
1150  }
1151 
1152  /* mode register: 256 color mode */
1153  vga_wgfx(regbase, VGA_GFX_MODE, 64);
1154 #ifdef CONFIG_PCI
1155  WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
1156 #elif defined(CONFIG_ZORRO)
1157  /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1158  WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1159 #endif
1160  }
1161 
1162  /******************************************************
1163  *
1164  * 24 bpp
1165  *
1166  */
1167 
1168  else if (var->bits_per_pixel == 24) {
1169  dev_dbg(info->device, "preparing for 24 bit deep display\n");
1170  switch (cinfo->btype) {
1171  case BT_PICCOLO:
1172  case BT_SPECTRUM:
1173  vga_wseq(regbase, CL_SEQR7, 0x85);
1174  /* Fast Page-Mode writes */
1175  vga_wseq(regbase, CL_SEQRF, 0xb0);
1176  break;
1177 
1178  case BT_PICASSO:
1179  vga_wseq(regbase, CL_SEQR7, 0x25);
1180  /* Fast Page-Mode writes */
1181  vga_wseq(regbase, CL_SEQRF, 0xb0);
1182  break;
1183 
1184  case BT_SD64:
1185  case BT_PICASSO4:
1186  case BT_ALPINE:
1187  /* Extended Sequencer Mode: 256c col. mode */
1188  vga_wseq(regbase, CL_SEQR7, 0xa5);
1189  break;
1190 
1191  case BT_GD5480:
1192  vga_wseq(regbase, CL_SEQR7, 0x15);
1193  /* We already set SRF and SR1F */
1194  break;
1195 
1196  case BT_LAGUNA:
1197  case BT_LAGUNAB:
1198  vga_wseq(regbase, CL_SEQR7,
1199  vga_rseq(regbase, CL_SEQR7) & ~0x01);
1200  control |= 0x4000;
1201  format |= 0x2400;
1202  threshold |= 0x20;
1203  break;
1204 
1205  default:
1206  dev_warn(info->device, "unknown Board\n");
1207  break;
1208  }
1209 
1210  /* mode register: 256 color mode */
1211  vga_wgfx(regbase, VGA_GFX_MODE, 64);
1212  /* hidden dac reg: 8-8-8 mode (24 or 32) */
1213  WHDR(cinfo, 0xc5);
1214  }
1215 
1216  /******************************************************
1217  *
1218  * unknown/unsupported bpp
1219  *
1220  */
1221 
1222  else
1223  dev_err(info->device,
1224  "What's this? requested color depth == %d.\n",
1225  var->bits_per_pixel);
1226 
1227  pitch = info->fix.line_length >> 3;
1228  vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1229  tmp = 0x22;
1230  if (pitch & 0x100)
1231  tmp |= 0x10; /* offset overflow bit */
1232 
1233  /* screen start addr #16-18, fastpagemode cycles */
1234  vga_wcrt(regbase, CL_CRT1B, tmp);
1235 
1236  /* screen start address bit 19 */
1237  if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1238  vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
1239 
1240  if (is_laguna(cinfo)) {
1241  tmp = 0;
1242  if ((htotal + 5) & 256)
1243  tmp |= 128;
1244  if (hdispend & 256)
1245  tmp |= 64;
1246  if (hsyncstart & 256)
1247  tmp |= 48;
1248  if (vtotal & 1024)
1249  tmp |= 8;
1250  if (vdispend & 1024)
1251  tmp |= 4;
1252  if (vsyncstart & 1024)
1253  tmp |= 3;
1254 
1255  vga_wcrt(regbase, CL_CRT1E, tmp);
1256  dev_dbg(info->device, "CRT1e: %d\n", tmp);
1257  }
1258 
1259  /* pixel panning */
1260  vga_wattr(regbase, CL_AR33, 0);
1261 
1262  /* [ EGS: SetOffset(); ] */
1263  /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1264  AttrOn(cinfo);
1265 
1266  if (is_laguna(cinfo)) {
1267  /* no tiles */
1268  fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1269  fb_writew(format, cinfo->laguna_mmio + 0xc0);
1270  fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1271  }
1272  /* finally, turn on everything - turn off "FullBandwidth" bit */
1273  /* also, set "DotClock%2" bit where requested */
1274  tmp = 0x01;
1275 
1276 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1277  if (var->vmode & FB_VMODE_CLOCK_HALVE)
1278  tmp |= 0x08;
1279 */
1280 
1281  vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1282  dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1283 
1284 #ifdef CIRRUSFB_DEBUG
1285  cirrusfb_dbg_reg_dump(info, NULL);
1286 #endif
1287 
1288  return 0;
1289 }
1290 
1291 /* for some reason incomprehensible to me, cirrusfb requires that you write
1292  * the registers twice for the settings to take..grr. -dte */
1293 static int cirrusfb_set_par(struct fb_info *info)
1294 {
1295  cirrusfb_set_par_foo(info);
1296  return cirrusfb_set_par_foo(info);
1297 }
1298 
1299 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1300  unsigned blue, unsigned transp,
1301  struct fb_info *info)
1302 {
1303  struct cirrusfb_info *cinfo = info->par;
1304 
1305  if (regno > 255)
1306  return -EINVAL;
1307 
1308  if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1309  u32 v;
1310  red >>= (16 - info->var.red.length);
1311  green >>= (16 - info->var.green.length);
1312  blue >>= (16 - info->var.blue.length);
1313 
1314  if (regno >= 16)
1315  return 1;
1316  v = (red << info->var.red.offset) |
1317  (green << info->var.green.offset) |
1318  (blue << info->var.blue.offset);
1319 
1320  cinfo->pseudo_palette[regno] = v;
1321  return 0;
1322  }
1323 
1324  if (info->var.bits_per_pixel == 8)
1325  WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1326 
1327  return 0;
1328 
1329 }
1330 
1331 /*************************************************************************
1332  cirrusfb_pan_display()
1333 
1334  performs display panning - provided hardware permits this
1335 **************************************************************************/
1336 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1337  struct fb_info *info)
1338 {
1339  int xoffset;
1340  unsigned long base;
1341  unsigned char tmp, xpix;
1342  struct cirrusfb_info *cinfo = info->par;
1343 
1344  /* no range checks for xoffset and yoffset, */
1345  /* as fb_pan_display has already done this */
1346  if (var->vmode & FB_VMODE_YWRAP)
1347  return -EINVAL;
1348 
1349  xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1350 
1351  base = var->yoffset * info->fix.line_length + xoffset;
1352 
1353  if (info->var.bits_per_pixel == 1) {
1354  /* base is already correct */
1355  xpix = (unsigned char) (var->xoffset % 8);
1356  } else {
1357  base /= 4;
1358  xpix = (unsigned char) ((xoffset % 4) * 2);
1359  }
1360 
1361  if (!is_laguna(cinfo))
1362  cirrusfb_WaitBLT(cinfo->regbase);
1363 
1364  /* lower 8 + 8 bits of screen start address */
1365  vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1366  vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1367 
1368  /* 0xf2 is %11110010, exclude tmp bits */
1369  tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1370  /* construct bits 16, 17 and 18 of screen start address */
1371  if (base & 0x10000)
1372  tmp |= 0x01;
1373  if (base & 0x20000)
1374  tmp |= 0x04;
1375  if (base & 0x40000)
1376  tmp |= 0x08;
1377 
1378  vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1379 
1380  /* construct bit 19 of screen start address */
1381  if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
1382  tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
1383  if (is_laguna(cinfo))
1384  tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
1385  else
1386  tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
1387  vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
1388  }
1389 
1390  /* write pixel panning value to AR33; this does not quite work in 8bpp
1391  *
1392  * ### Piccolo..? Will this work?
1393  */
1394  if (info->var.bits_per_pixel == 1)
1395  vga_wattr(cinfo->regbase, CL_AR33, xpix);
1396 
1397  return 0;
1398 }
1399 
1400 static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1401 {
1402  /*
1403  * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1404  * then the caller blanks by setting the CLUT (Color Look Up Table)
1405  * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1406  * failed due to e.g. a video mode which doesn't support it.
1407  * Implements VESA suspend and powerdown modes on hardware that
1408  * supports disabling hsync/vsync:
1409  * blank_mode == 2: suspend vsync
1410  * blank_mode == 3: suspend hsync
1411  * blank_mode == 4: powerdown
1412  */
1413  unsigned char val;
1414  struct cirrusfb_info *cinfo = info->par;
1415  int current_mode = cinfo->blank_mode;
1416 
1417  dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1418 
1419  if (info->state != FBINFO_STATE_RUNNING ||
1420  current_mode == blank_mode) {
1421  dev_dbg(info->device, "EXIT, returning 0\n");
1422  return 0;
1423  }
1424 
1425  /* Undo current */
1426  if (current_mode == FB_BLANK_NORMAL ||
1427  current_mode == FB_BLANK_UNBLANK)
1428  /* clear "FullBandwidth" bit */
1429  val = 0;
1430  else
1431  /* set "FullBandwidth" bit */
1432  val = 0x20;
1433 
1434  val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1435  vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1436 
1437  switch (blank_mode) {
1438  case FB_BLANK_UNBLANK:
1439  case FB_BLANK_NORMAL:
1440  val = 0x00;
1441  break;
1443  val = 0x04;
1444  break;
1446  val = 0x02;
1447  break;
1448  case FB_BLANK_POWERDOWN:
1449  val = 0x06;
1450  break;
1451  default:
1452  dev_dbg(info->device, "EXIT, returning 1\n");
1453  return 1;
1454  }
1455 
1456  vga_wgfx(cinfo->regbase, CL_GRE, val);
1457 
1458  cinfo->blank_mode = blank_mode;
1459  dev_dbg(info->device, "EXIT, returning 0\n");
1460 
1461  /* Let fbcon do a soft blank for us */
1462  return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1463 }
1464 
1465 /**** END Hardware specific Routines **************************************/
1466 /****************************************************************************/
1467 /**** BEGIN Internal Routines ***********************************************/
1468 
1469 static void init_vgachip(struct fb_info *info)
1470 {
1471  struct cirrusfb_info *cinfo = info->par;
1472  const struct cirrusfb_board_info_rec *bi;
1473 
1474  assert(cinfo != NULL);
1475 
1476  bi = &cirrusfb_board_info[cinfo->btype];
1477 
1478  /* reset board globally */
1479  switch (cinfo->btype) {
1480  case BT_PICCOLO:
1481  WSFR(cinfo, 0x01);
1482  udelay(500);
1483  WSFR(cinfo, 0x51);
1484  udelay(500);
1485  break;
1486  case BT_PICASSO:
1487  WSFR2(cinfo, 0xff);
1488  udelay(500);
1489  break;
1490  case BT_SD64:
1491  case BT_SPECTRUM:
1492  WSFR(cinfo, 0x1f);
1493  udelay(500);
1494  WSFR(cinfo, 0x4f);
1495  udelay(500);
1496  break;
1497  case BT_PICASSO4:
1498  /* disable flickerfixer */
1499  vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1500  mdelay(100);
1501  /* mode */
1502  vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1503  case BT_GD5480: /* fall through */
1504  /* from Klaus' NetBSD driver: */
1505  vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1506  case BT_ALPINE: /* fall through */
1507  /* put blitter into 542x compat */
1508  vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1509  break;
1510 
1511  case BT_LAGUNA:
1512  case BT_LAGUNAB:
1513  /* Nothing to do to reset the board. */
1514  break;
1515 
1516  default:
1517  dev_err(info->device, "Warning: Unknown board type\n");
1518  break;
1519  }
1520 
1521  /* make sure RAM size set by this point */
1522  assert(info->screen_size > 0);
1523 
1524  /* the P4 is not fully initialized here; I rely on it having been */
1525  /* inited under AmigaOS already, which seems to work just fine */
1526  /* (Klaus advised to do it this way) */
1527 
1528  if (cinfo->btype != BT_PICASSO4) {
1529  WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1530  WGen(cinfo, CL_POS102, 0x01);
1531  WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1532 
1533  if (cinfo->btype != BT_SD64)
1534  WGen(cinfo, CL_VSSM2, 0x01);
1535 
1536  /* reset sequencer logic */
1537  vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1538 
1539  /* FullBandwidth (video off) and 8/9 dot clock */
1540  vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1541 
1542  /* "magic cookie" - doesn't make any sense to me.. */
1543 /* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1544  /* unlock all extension registers */
1545  vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1546 
1547  switch (cinfo->btype) {
1548  case BT_GD5480:
1549  vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1550  break;
1551  case BT_ALPINE:
1552  case BT_LAGUNA:
1553  case BT_LAGUNAB:
1554  break;
1555  case BT_SD64:
1556 #ifdef CONFIG_ZORRO
1557  vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1558 #endif
1559  break;
1560  default:
1561  vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1562  vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1563  break;
1564  }
1565  }
1566  /* plane mask: nothing */
1567  vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1568  /* character map select: doesn't even matter in gx mode */
1569  vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1570  /* memory mode: chain4, ext. memory */
1571  vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1572 
1573  /* controller-internal base address of video memory */
1574  if (bi->init_sr07)
1575  vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1576 
1577  /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1578  /* EEPROM control: shouldn't be necessary to write to this at all.. */
1579 
1580  /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1581  vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1582  /* graphics cursor Y position (..."... ) */
1583  vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1584  /* graphics cursor attributes */
1585  vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1586  /* graphics cursor pattern address */
1587  vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1588 
1589  /* writing these on a P4 might give problems.. */
1590  if (cinfo->btype != BT_PICASSO4) {
1591  /* configuration readback and ext. color */
1592  vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1593  /* signature generator */
1594  vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1595  }
1596 
1597  /* Screen A preset row scan: none */
1598  vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1599  /* Text cursor start: disable text cursor */
1600  vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1601  /* Text cursor end: - */
1602  vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1603  /* text cursor location high: 0 */
1604  vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1605  /* text cursor location low: 0 */
1606  vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1607 
1608  /* Underline Row scanline: - */
1609  vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1610  /* ### add 0x40 for text modes with > 30 MHz pixclock */
1611  /* ext. display controls: ext.adr. wrap */
1612  vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1613 
1614  /* Set/Reset registers: - */
1615  vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1616  /* Set/Reset enable: - */
1617  vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1618  /* Color Compare: - */
1619  vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1620  /* Data Rotate: - */
1621  vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1622  /* Read Map Select: - */
1623  vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1624  /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1625  vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1626  /* Miscellaneous: memory map base address, graphics mode */
1627  vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1628  /* Color Don't care: involve all planes */
1629  vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1630  /* Bit Mask: no mask at all */
1631  vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1632 
1633  if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1634  is_laguna(cinfo))
1635  /* (5434 can't have bit 3 set for bitblt) */
1636  vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1637  else
1638  /* Graphics controller mode extensions: finer granularity,
1639  * 8byte data latches
1640  */
1641  vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1642 
1643  vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1644  vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1645  vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1646  /* Background color byte 1: - */
1647  /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1648  /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1649 
1650  /* Attribute Controller palette registers: "identity mapping" */
1651  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1652  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1653  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1654  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1655  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1656  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1657  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1658  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1659  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1660  vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1661  vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1662  vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1663  vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1664  vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1665  vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1666  vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1667 
1668  /* Attribute Controller mode: graphics mode */
1669  vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1670  /* Overscan color reg.: reg. 0 */
1671  vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1672  /* Color Plane enable: Enable all 4 planes */
1673  vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1674  /* Color Select: - */
1675  vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1676 
1677  WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1678 
1679  /* BLT Start/status: Blitter reset */
1680  vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1681  /* - " - : "end-of-reset" */
1682  vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1683 
1684  /* misc... */
1685  WHDR(cinfo, 0); /* Hidden DAC register: - */
1686  return;
1687 }
1688 
1689 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1690 {
1691 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1692  static int IsOn = 0; /* XXX not ok for multiple boards */
1693 
1694  if (cinfo->btype == BT_PICASSO4)
1695  return; /* nothing to switch */
1696  if (cinfo->btype == BT_ALPINE)
1697  return; /* nothing to switch */
1698  if (cinfo->btype == BT_GD5480)
1699  return; /* nothing to switch */
1700  if (cinfo->btype == BT_PICASSO) {
1701  if ((on && !IsOn) || (!on && IsOn))
1702  WSFR(cinfo, 0xff);
1703  return;
1704  }
1705  if (on) {
1706  switch (cinfo->btype) {
1707  case BT_SD64:
1708  WSFR(cinfo, cinfo->SFR | 0x21);
1709  break;
1710  case BT_PICCOLO:
1711  WSFR(cinfo, cinfo->SFR | 0x28);
1712  break;
1713  case BT_SPECTRUM:
1714  WSFR(cinfo, 0x6f);
1715  break;
1716  default: /* do nothing */ break;
1717  }
1718  } else {
1719  switch (cinfo->btype) {
1720  case BT_SD64:
1721  WSFR(cinfo, cinfo->SFR & 0xde);
1722  break;
1723  case BT_PICCOLO:
1724  WSFR(cinfo, cinfo->SFR & 0xd7);
1725  break;
1726  case BT_SPECTRUM:
1727  WSFR(cinfo, 0x4f);
1728  break;
1729  default: /* do nothing */
1730  break;
1731  }
1732  }
1733 #endif /* CONFIG_ZORRO */
1734 }
1735 
1736 /******************************************/
1737 /* Linux 2.6-style accelerated functions */
1738 /******************************************/
1739 
1740 static int cirrusfb_sync(struct fb_info *info)
1741 {
1742  struct cirrusfb_info *cinfo = info->par;
1743 
1744  if (!is_laguna(cinfo)) {
1745  while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1746  cpu_relax();
1747  }
1748  return 0;
1749 }
1750 
1751 static void cirrusfb_fillrect(struct fb_info *info,
1752  const struct fb_fillrect *region)
1753 {
1754  struct fb_fillrect modded;
1755  int vxres, vyres;
1756  struct cirrusfb_info *cinfo = info->par;
1757  int m = info->var.bits_per_pixel;
1758  u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1759  cinfo->pseudo_palette[region->color] : region->color;
1760 
1761  if (info->state != FBINFO_STATE_RUNNING)
1762  return;
1763  if (info->flags & FBINFO_HWACCEL_DISABLED) {
1764  cfb_fillrect(info, region);
1765  return;
1766  }
1767 
1768  vxres = info->var.xres_virtual;
1769  vyres = info->var.yres_virtual;
1770 
1771  memcpy(&modded, region, sizeof(struct fb_fillrect));
1772 
1773  if (!modded.width || !modded.height ||
1774  modded.dx >= vxres || modded.dy >= vyres)
1775  return;
1776 
1777  if (modded.dx + modded.width > vxres)
1778  modded.width = vxres - modded.dx;
1779  if (modded.dy + modded.height > vyres)
1780  modded.height = vyres - modded.dy;
1781 
1782  cirrusfb_RectFill(cinfo->regbase,
1783  info->var.bits_per_pixel,
1784  (region->dx * m) / 8, region->dy,
1785  (region->width * m) / 8, region->height,
1786  color, color,
1787  info->fix.line_length, 0x40);
1788 }
1789 
1790 static void cirrusfb_copyarea(struct fb_info *info,
1791  const struct fb_copyarea *area)
1792 {
1793  struct fb_copyarea modded;
1794  u32 vxres, vyres;
1795  struct cirrusfb_info *cinfo = info->par;
1796  int m = info->var.bits_per_pixel;
1797 
1798  if (info->state != FBINFO_STATE_RUNNING)
1799  return;
1800  if (info->flags & FBINFO_HWACCEL_DISABLED) {
1801  cfb_copyarea(info, area);
1802  return;
1803  }
1804 
1805  vxres = info->var.xres_virtual;
1806  vyres = info->var.yres_virtual;
1807  memcpy(&modded, area, sizeof(struct fb_copyarea));
1808 
1809  if (!modded.width || !modded.height ||
1810  modded.sx >= vxres || modded.sy >= vyres ||
1811  modded.dx >= vxres || modded.dy >= vyres)
1812  return;
1813 
1814  if (modded.sx + modded.width > vxres)
1815  modded.width = vxres - modded.sx;
1816  if (modded.dx + modded.width > vxres)
1817  modded.width = vxres - modded.dx;
1818  if (modded.sy + modded.height > vyres)
1819  modded.height = vyres - modded.sy;
1820  if (modded.dy + modded.height > vyres)
1821  modded.height = vyres - modded.dy;
1822 
1823  cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1824  (area->sx * m) / 8, area->sy,
1825  (area->dx * m) / 8, area->dy,
1826  (area->width * m) / 8, area->height,
1827  info->fix.line_length);
1828 
1829 }
1830 
1831 static void cirrusfb_imageblit(struct fb_info *info,
1832  const struct fb_image *image)
1833 {
1834  struct cirrusfb_info *cinfo = info->par;
1835  unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1836 
1837  if (info->state != FBINFO_STATE_RUNNING)
1838  return;
1839  /* Alpine/SD64 does not work at 24bpp ??? */
1840  if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1841  cfb_imageblit(info, image);
1842  else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1843  op == 0xc)
1844  cfb_imageblit(info, image);
1845  else {
1846  unsigned size = ((image->width + 7) >> 3) * image->height;
1847  int m = info->var.bits_per_pixel;
1848  u32 fg, bg;
1849 
1850  if (info->var.bits_per_pixel == 8) {
1851  fg = image->fg_color;
1852  bg = image->bg_color;
1853  } else {
1854  fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1855  bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1856  }
1857  if (info->var.bits_per_pixel == 24) {
1858  /* clear background first */
1859  cirrusfb_RectFill(cinfo->regbase,
1860  info->var.bits_per_pixel,
1861  (image->dx * m) / 8, image->dy,
1862  (image->width * m) / 8,
1863  image->height,
1864  bg, bg,
1865  info->fix.line_length, 0x40);
1866  }
1867  cirrusfb_RectFill(cinfo->regbase,
1868  info->var.bits_per_pixel,
1869  (image->dx * m) / 8, image->dy,
1870  (image->width * m) / 8, image->height,
1871  fg, bg,
1872  info->fix.line_length, op);
1873  memcpy(info->screen_base, image->data, size);
1874  }
1875 }
1876 
1877 #ifdef CONFIG_PPC_PREP
1878 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1879 #define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
1880 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1881 {
1882  *display = PREP_VIDEO_BASE;
1883  *registers = (unsigned long) PREP_IO_BASE;
1884 }
1885 
1886 #endif /* CONFIG_PPC_PREP */
1887 
1888 #ifdef CONFIG_PCI
1889 static int release_io_ports;
1890 
1891 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1892  * based on the DRAM bandwidth bit and DRAM bank switching bit. This
1893  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1894  * seem to have. */
1895 static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1896  u8 __iomem *regbase)
1897 {
1898  unsigned long mem;
1899  struct cirrusfb_info *cinfo = info->par;
1900 
1901  if (is_laguna(cinfo)) {
1902  unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1903 
1904  mem = ((SR14 & 7) + 1) << 20;
1905  } else {
1906  unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1907  switch ((SRF & 0x18)) {
1908  case 0x08:
1909  mem = 512 * 1024;
1910  break;
1911  case 0x10:
1912  mem = 1024 * 1024;
1913  break;
1914  /* 64-bit DRAM data bus width; assume 2MB.
1915  * Also indicates 2MB memory on the 5430.
1916  */
1917  case 0x18:
1918  mem = 2048 * 1024;
1919  break;
1920  default:
1921  dev_warn(info->device, "Unknown memory size!\n");
1922  mem = 1024 * 1024;
1923  }
1924  /* If DRAM bank switching is enabled, there must be
1925  * twice as much memory installed. (4MB on the 5434)
1926  */
1927  if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1928  mem *= 2;
1929  }
1930 
1931  /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1932  return mem;
1933 }
1934 
1935 static void get_pci_addrs(const struct pci_dev *pdev,
1936  unsigned long *display, unsigned long *registers)
1937 {
1938  assert(pdev != NULL);
1939  assert(display != NULL);
1940  assert(registers != NULL);
1941 
1942  *display = 0;
1943  *registers = 0;
1944 
1945  /* This is a best-guess for now */
1946 
1947  if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1948  *display = pci_resource_start(pdev, 1);
1949  *registers = pci_resource_start(pdev, 0);
1950  } else {
1951  *display = pci_resource_start(pdev, 0);
1952  *registers = pci_resource_start(pdev, 1);
1953  }
1954 
1955  assert(*display != 0);
1956 }
1957 
1958 static void cirrusfb_pci_unmap(struct fb_info *info)
1959 {
1960  struct pci_dev *pdev = to_pci_dev(info->device);
1961  struct cirrusfb_info *cinfo = info->par;
1962 
1963  if (cinfo->laguna_mmio == NULL)
1964  iounmap(cinfo->laguna_mmio);
1965  iounmap(info->screen_base);
1966 #if 0 /* if system didn't claim this region, we would... */
1967  release_mem_region(0xA0000, 65535);
1968 #endif
1969  if (release_io_ports)
1970  release_region(0x3C0, 32);
1971  pci_release_regions(pdev);
1972 }
1973 #endif /* CONFIG_PCI */
1974 
1975 #ifdef CONFIG_ZORRO
1976 static void cirrusfb_zorro_unmap(struct fb_info *info)
1977 {
1978  struct cirrusfb_info *cinfo = info->par;
1979  struct zorro_dev *zdev = to_zorro_dev(info->device);
1980 
1981  if (info->fix.smem_start > 16 * MB_)
1982  iounmap(info->screen_base);
1983  if (info->fix.mmio_start > 16 * MB_)
1984  iounmap(cinfo->regbase);
1985 
1986  zorro_release_device(zdev);
1987 }
1988 #endif /* CONFIG_ZORRO */
1989 
1990 /* function table of the above functions */
1991 static struct fb_ops cirrusfb_ops = {
1992  .owner = THIS_MODULE,
1993  .fb_open = cirrusfb_open,
1994  .fb_release = cirrusfb_release,
1995  .fb_setcolreg = cirrusfb_setcolreg,
1996  .fb_check_var = cirrusfb_check_var,
1997  .fb_set_par = cirrusfb_set_par,
1998  .fb_pan_display = cirrusfb_pan_display,
1999  .fb_blank = cirrusfb_blank,
2000  .fb_fillrect = cirrusfb_fillrect,
2001  .fb_copyarea = cirrusfb_copyarea,
2002  .fb_sync = cirrusfb_sync,
2003  .fb_imageblit = cirrusfb_imageblit,
2004 };
2005 
2006 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2007 {
2008  struct cirrusfb_info *cinfo = info->par;
2009  struct fb_var_screeninfo *var = &info->var;
2010 
2011  info->pseudo_palette = cinfo->pseudo_palette;
2012  info->flags = FBINFO_DEFAULT
2018  if (noaccel || is_laguna(cinfo)) {
2019  info->flags |= FBINFO_HWACCEL_DISABLED;
2020  info->fix.accel = FB_ACCEL_NONE;
2021  } else
2022  info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
2023 
2024  info->fbops = &cirrusfb_ops;
2025 
2026  if (cinfo->btype == BT_GD5480) {
2027  if (var->bits_per_pixel == 16)
2028  info->screen_base += 1 * MB_;
2029  if (var->bits_per_pixel == 32)
2030  info->screen_base += 2 * MB_;
2031  }
2032 
2033  /* Fill fix common fields */
2034  strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2035  sizeof(info->fix.id));
2036 
2037  /* monochrome: only 1 memory plane */
2038  /* 8 bit and above: Use whole memory area */
2039  info->fix.smem_len = info->screen_size;
2040  if (var->bits_per_pixel == 1)
2041  info->fix.smem_len /= 4;
2042  info->fix.type_aux = 0;
2043  info->fix.xpanstep = 1;
2044  info->fix.ypanstep = 1;
2045  info->fix.ywrapstep = 0;
2046 
2047  /* FIXME: map region at 0xB8000 if available, fill in here */
2048  info->fix.mmio_len = 0;
2049 
2050  fb_alloc_cmap(&info->cmap, 256, 0);
2051 
2052  return 0;
2053 }
2054 
2055 static int __devinit cirrusfb_register(struct fb_info *info)
2056 {
2057  struct cirrusfb_info *cinfo = info->par;
2058  int err;
2059 
2060  /* sanity checks */
2061  assert(cinfo->btype != BT_NONE);
2062 
2063  /* set all the vital stuff */
2064  cirrusfb_set_fbinfo(info);
2065 
2066  dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2067 
2068  err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2069  if (!err) {
2070  dev_dbg(info->device, "wrong initial video mode\n");
2071  err = -EINVAL;
2072  goto err_dealloc_cmap;
2073  }
2074 
2075  info->var.activate = FB_ACTIVATE_NOW;
2076 
2077  err = cirrusfb_check_var(&info->var, info);
2078  if (err < 0) {
2079  /* should never happen */
2080  dev_dbg(info->device,
2081  "choking on default var... umm, no good.\n");
2082  goto err_dealloc_cmap;
2083  }
2084 
2085  err = register_framebuffer(info);
2086  if (err < 0) {
2087  dev_err(info->device,
2088  "could not register fb device; err = %d!\n", err);
2089  goto err_dealloc_cmap;
2090  }
2091 
2092  return 0;
2093 
2094 err_dealloc_cmap:
2095  fb_dealloc_cmap(&info->cmap);
2096  return err;
2097 }
2098 
2099 static void __devexit cirrusfb_cleanup(struct fb_info *info)
2100 {
2101  struct cirrusfb_info *cinfo = info->par;
2102 
2103  switch_monitor(cinfo, 0);
2104  unregister_framebuffer(info);
2105  fb_dealloc_cmap(&info->cmap);
2106  dev_dbg(info->device, "Framebuffer unregistered\n");
2107  cinfo->unmap(info);
2108  framebuffer_release(info);
2109 }
2110 
2111 #ifdef CONFIG_PCI
2112 static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2113  const struct pci_device_id *ent)
2114 {
2115  struct cirrusfb_info *cinfo;
2116  struct fb_info *info;
2117  unsigned long board_addr, board_size;
2118  int ret;
2119 
2120  ret = pci_enable_device(pdev);
2121  if (ret < 0) {
2122  printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2123  goto err_out;
2124  }
2125 
2126  info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2127  if (!info) {
2128  printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2129  ret = -ENOMEM;
2130  goto err_out;
2131  }
2132 
2133  cinfo = info->par;
2134  cinfo->btype = (enum cirrus_board) ent->driver_data;
2135 
2136  dev_dbg(info->device,
2137  " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2138  (unsigned long long)pdev->resource[0].start, cinfo->btype);
2139  dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2140  (unsigned long long)pdev->resource[1].start);
2141 
2142  if (isPReP) {
2143  pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2144 #ifdef CONFIG_PPC_PREP
2145  get_prep_addrs(&board_addr, &info->fix.mmio_start);
2146 #endif
2147  /* PReP dies if we ioremap the IO registers, but it works w/out... */
2148  cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2149  } else {
2150  dev_dbg(info->device,
2151  "Attempt to get PCI info for Cirrus Graphics Card\n");
2152  get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2153  /* FIXME: this forces VGA. alternatives? */
2154  cinfo->regbase = NULL;
2155  cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2156  }
2157 
2158  dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2159  board_addr, info->fix.mmio_start);
2160 
2161  board_size = (cinfo->btype == BT_GD5480) ?
2162  32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2163 
2164  ret = pci_request_regions(pdev, "cirrusfb");
2165  if (ret < 0) {
2166  dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2167  board_addr);
2168  goto err_release_fb;
2169  }
2170 #if 0 /* if the system didn't claim this region, we would... */
2171  if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2172  dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2173  0xA0000L);
2174  ret = -EBUSY;
2175  goto err_release_regions;
2176  }
2177 #endif
2178  if (request_region(0x3C0, 32, "cirrusfb"))
2179  release_io_ports = 1;
2180 
2181  info->screen_base = ioremap(board_addr, board_size);
2182  if (!info->screen_base) {
2183  ret = -EIO;
2184  goto err_release_legacy;
2185  }
2186 
2187  info->fix.smem_start = board_addr;
2188  info->screen_size = board_size;
2189  cinfo->unmap = cirrusfb_pci_unmap;
2190 
2191  dev_info(info->device,
2192  "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2193  info->screen_size >> 10, board_addr);
2194  pci_set_drvdata(pdev, info);
2195 
2196  ret = cirrusfb_register(info);
2197  if (!ret)
2198  return 0;
2199 
2200  pci_set_drvdata(pdev, NULL);
2201  iounmap(info->screen_base);
2202 err_release_legacy:
2203  if (release_io_ports)
2204  release_region(0x3C0, 32);
2205 #if 0
2206  release_mem_region(0xA0000, 65535);
2207 err_release_regions:
2208 #endif
2209  pci_release_regions(pdev);
2210 err_release_fb:
2211  if (cinfo->laguna_mmio != NULL)
2212  iounmap(cinfo->laguna_mmio);
2213  framebuffer_release(info);
2214 err_out:
2215  return ret;
2216 }
2217 
2218 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2219 {
2220  struct fb_info *info = pci_get_drvdata(pdev);
2221 
2222  cirrusfb_cleanup(info);
2223 }
2224 
2225 static struct pci_driver cirrusfb_pci_driver = {
2226  .name = "cirrusfb",
2227  .id_table = cirrusfb_pci_table,
2228  .probe = cirrusfb_pci_register,
2229  .remove = __devexit_p(cirrusfb_pci_unregister),
2230 #ifdef CONFIG_PM
2231 #if 0
2232  .suspend = cirrusfb_pci_suspend,
2233  .resume = cirrusfb_pci_resume,
2234 #endif
2235 #endif
2236 };
2237 #endif /* CONFIG_PCI */
2238 
2239 #ifdef CONFIG_ZORRO
2240 static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2241  const struct zorro_device_id *ent)
2242 {
2243  struct fb_info *info;
2244  int error;
2245  const struct zorrocl *zcl;
2246  enum cirrus_board btype;
2247  unsigned long regbase, ramsize, rambase;
2248  struct cirrusfb_info *cinfo;
2249 
2250  info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2251  if (!info) {
2252  printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2253  return -ENOMEM;
2254  }
2255 
2256  zcl = (const struct zorrocl *)ent->driver_data;
2257  btype = zcl->type;
2258  regbase = zorro_resource_start(z) + zcl->regoffset;
2259  ramsize = zcl->ramsize;
2260  if (ramsize) {
2261  rambase = zorro_resource_start(z) + zcl->ramoffset;
2262  if (zorro_resource_len(z) == 64 * MB_) {
2263  /* Quirk for 64 MiB Picasso IV */
2264  rambase += zcl->ramoffset;
2265  }
2266  } else {
2267  struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2268  if (!ram || !zorro_resource_len(ram)) {
2269  dev_err(info->device, "No video RAM found\n");
2270  error = -ENODEV;
2271  goto err_release_fb;
2272  }
2273  rambase = zorro_resource_start(ram);
2274  ramsize = zorro_resource_len(ram);
2275  if (zcl->ramid2 &&
2276  (ram = zorro_find_device(zcl->ramid2, NULL))) {
2277  if (zorro_resource_start(ram) != rambase + ramsize) {
2278  dev_warn(info->device,
2279  "Skipping non-contiguous RAM at %pR\n",
2280  &ram->resource);
2281  } else {
2282  ramsize += zorro_resource_len(ram);
2283  }
2284  }
2285  }
2286 
2287  dev_info(info->device,
2288  "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2289  cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2290  rambase);
2291 
2292  if (!zorro_request_device(z, "cirrusfb")) {
2293  dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2294  error = -EBUSY;
2295  goto err_release_fb;
2296  }
2297 
2298  cinfo = info->par;
2299  cinfo->btype = btype;
2300 
2301  info->fix.mmio_start = regbase;
2302  cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2303  : (caddr_t)ZTWO_VADDR(regbase);
2304  if (!cinfo->regbase) {
2305  dev_err(info->device, "Cannot map registers\n");
2306  error = -EIO;
2307  goto err_release_dev;
2308  }
2309 
2310  info->fix.smem_start = rambase;
2311  info->screen_size = ramsize;
2312  info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2313  : (caddr_t)ZTWO_VADDR(rambase);
2314  if (!info->screen_base) {
2315  dev_err(info->device, "Cannot map video RAM\n");
2316  error = -EIO;
2317  goto err_unmap_reg;
2318  }
2319 
2320  cinfo->unmap = cirrusfb_zorro_unmap;
2321 
2322  dev_info(info->device,
2323  "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2324  ramsize / MB_, rambase);
2325 
2326  /* MCLK select etc. */
2327  if (cirrusfb_board_info[btype].init_sr1f)
2328  vga_wseq(cinfo->regbase, CL_SEQR1F,
2329  cirrusfb_board_info[btype].sr1f);
2330 
2331  error = cirrusfb_register(info);
2332  if (error) {
2333  dev_err(info->device, "Failed to register device, error %d\n",
2334  error);
2335  goto err_unmap_ram;
2336  }
2337 
2338  zorro_set_drvdata(z, info);
2339  return 0;
2340 
2341 err_unmap_ram:
2342  if (rambase > 16 * MB_)
2343  iounmap(info->screen_base);
2344 
2345 err_unmap_reg:
2346  if (regbase > 16 * MB_)
2347  iounmap(cinfo->regbase);
2348 err_release_dev:
2349  zorro_release_device(z);
2350 err_release_fb:
2351  framebuffer_release(info);
2352  return error;
2353 }
2354 
2355 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2356 {
2357  struct fb_info *info = zorro_get_drvdata(z);
2358 
2359  cirrusfb_cleanup(info);
2360  zorro_set_drvdata(z, NULL);
2361 }
2362 
2363 static struct zorro_driver cirrusfb_zorro_driver = {
2364  .name = "cirrusfb",
2365  .id_table = cirrusfb_zorro_table,
2366  .probe = cirrusfb_zorro_register,
2367  .remove = __devexit_p(cirrusfb_zorro_unregister),
2368 };
2369 #endif /* CONFIG_ZORRO */
2370 
2371 #ifndef MODULE
2372 static int __init cirrusfb_setup(char *options)
2373 {
2374  char *this_opt;
2375 
2376  if (!options || !*options)
2377  return 0;
2378 
2379  while ((this_opt = strsep(&options, ",")) != NULL) {
2380  if (!*this_opt)
2381  continue;
2382 
2383  if (!strcmp(this_opt, "noaccel"))
2384  noaccel = 1;
2385  else if (!strncmp(this_opt, "mode:", 5))
2386  mode_option = this_opt + 5;
2387  else
2388  mode_option = this_opt;
2389  }
2390  return 0;
2391 }
2392 #endif
2393 
2394  /*
2395  * Modularization
2396  */
2397 
2398 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <[email protected]>");
2399 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2400 MODULE_LICENSE("GPL");
2401 
2402 static int __init cirrusfb_init(void)
2403 {
2404  int error = 0;
2405 
2406 #ifndef MODULE
2407  char *option = NULL;
2408 
2409  if (fb_get_options("cirrusfb", &option))
2410  return -ENODEV;
2411  cirrusfb_setup(option);
2412 #endif
2413 
2414 #ifdef CONFIG_ZORRO
2415  error |= zorro_register_driver(&cirrusfb_zorro_driver);
2416 #endif
2417 #ifdef CONFIG_PCI
2418  error |= pci_register_driver(&cirrusfb_pci_driver);
2419 #endif
2420  return error;
2421 }
2422 
2423 static void __exit cirrusfb_exit(void)
2424 {
2425 #ifdef CONFIG_PCI
2426  pci_unregister_driver(&cirrusfb_pci_driver);
2427 #endif
2428 #ifdef CONFIG_ZORRO
2429  zorro_unregister_driver(&cirrusfb_zorro_driver);
2430 #endif
2431 }
2432 
2433 module_init(cirrusfb_init);
2434 
2435 module_param(mode_option, charp, 0);
2436 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2437 module_param(noaccel, bool, 0);
2438 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2439 
2440 #ifdef MODULE
2441 module_exit(cirrusfb_exit);
2442 #endif
2443 
2444 /**********************************************************************/
2445 /* about the following functions - I have used the same names for the */
2446 /* functions as Markus Wild did in his Retina driver for NetBSD as */
2447 /* they just made sense for this purpose. Apart from that, I wrote */
2448 /* these functions myself. */
2449 /**********************************************************************/
2450 
2451 /*** WGen() - write into one of the external/general registers ***/
2452 static void WGen(const struct cirrusfb_info *cinfo,
2453  int regnum, unsigned char val)
2454 {
2455  unsigned long regofs = 0;
2456 
2457  if (cinfo->btype == BT_PICASSO) {
2458  /* Picasso II specific hack */
2459 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2460  regnum == CL_VSSM2) */
2461  if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2462  regofs = 0xfff;
2463  }
2464 
2465  vga_w(cinfo->regbase, regofs + regnum, val);
2466 }
2467 
2468 /*** RGen() - read out one of the external/general registers ***/
2469 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2470 {
2471  unsigned long regofs = 0;
2472 
2473  if (cinfo->btype == BT_PICASSO) {
2474  /* Picasso II specific hack */
2475 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2476  regnum == CL_VSSM2) */
2477  if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2478  regofs = 0xfff;
2479  }
2480 
2481  return vga_r(cinfo->regbase, regofs + regnum);
2482 }
2483 
2484 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2485 static void AttrOn(const struct cirrusfb_info *cinfo)
2486 {
2487  assert(cinfo != NULL);
2488 
2489  if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2490  /* if we're just in "write value" mode, write back the */
2491  /* same value as before to not modify anything */
2492  vga_w(cinfo->regbase, VGA_ATT_IW,
2493  vga_r(cinfo->regbase, VGA_ATT_R));
2494  }
2495  /* turn on video bit */
2496 /* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2497  vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2498 
2499  /* dummy write on Reg0 to be on "write index" mode next time */
2500  vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2501 }
2502 
2503 /*** WHDR() - write into the Hidden DAC register ***/
2504 /* as the HDR is the only extension register that requires special treatment
2505  * (the other extension registers are accessible just like the "ordinary"
2506  * registers of their functional group) here is a specialized routine for
2507  * accessing the HDR
2508  */
2509 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2510 {
2511  unsigned char dummy;
2512 
2513  if (is_laguna(cinfo))
2514  return;
2515  if (cinfo->btype == BT_PICASSO) {
2516  /* Klaus' hint for correct access to HDR on some boards */
2517  /* first write 0 to pixel mask (3c6) */
2518  WGen(cinfo, VGA_PEL_MSK, 0x00);
2519  udelay(200);
2520  /* next read dummy from pixel address (3c8) */
2521  dummy = RGen(cinfo, VGA_PEL_IW);
2522  udelay(200);
2523  }
2524  /* now do the usual stuff to access the HDR */
2525 
2526  dummy = RGen(cinfo, VGA_PEL_MSK);
2527  udelay(200);
2528  dummy = RGen(cinfo, VGA_PEL_MSK);
2529  udelay(200);
2530  dummy = RGen(cinfo, VGA_PEL_MSK);
2531  udelay(200);
2532  dummy = RGen(cinfo, VGA_PEL_MSK);
2533  udelay(200);
2534 
2535  WGen(cinfo, VGA_PEL_MSK, val);
2536  udelay(200);
2537 
2538  if (cinfo->btype == BT_PICASSO) {
2539  /* now first reset HDR access counter */
2540  dummy = RGen(cinfo, VGA_PEL_IW);
2541  udelay(200);
2542 
2543  /* and at the end, restore the mask value */
2544  /* ## is this mask always 0xff? */
2545  WGen(cinfo, VGA_PEL_MSK, 0xff);
2546  udelay(200);
2547  }
2548 }
2549 
2550 /*** WSFR() - write to the "special function register" (SFR) ***/
2551 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2552 {
2553 #ifdef CONFIG_ZORRO
2554  assert(cinfo->regbase != NULL);
2555  cinfo->SFR = val;
2556  z_writeb(val, cinfo->regbase + 0x8000);
2557 #endif
2558 }
2559 
2560 /* The Picasso has a second register for switching the monitor bit */
2561 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2562 {
2563 #ifdef CONFIG_ZORRO
2564  /* writing an arbitrary value to this one causes the monitor switcher */
2565  /* to flip to Amiga display */
2566  assert(cinfo->regbase != NULL);
2567  cinfo->SFR = val;
2568  z_writeb(val, cinfo->regbase + 0x9000);
2569 #endif
2570 }
2571 
2572 /*** WClut - set CLUT entry (range: 0..63) ***/
2573 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2574  unsigned char green, unsigned char blue)
2575 {
2576  unsigned int data = VGA_PEL_D;
2577 
2578  /* address write mode register is not translated.. */
2579  vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2580 
2581  if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2582  cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2583  cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2584  /* but DAC data register IS, at least for Picasso II */
2585  if (cinfo->btype == BT_PICASSO)
2586  data += 0xfff;
2587  vga_w(cinfo->regbase, data, red);
2588  vga_w(cinfo->regbase, data, green);
2589  vga_w(cinfo->regbase, data, blue);
2590  } else {
2591  vga_w(cinfo->regbase, data, blue);
2592  vga_w(cinfo->regbase, data, green);
2593  vga_w(cinfo->regbase, data, red);
2594  }
2595 }
2596 
2597 #if 0
2598 /*** RClut - read CLUT entry (range 0..63) ***/
2599 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2600  unsigned char *green, unsigned char *blue)
2601 {
2602  unsigned int data = VGA_PEL_D;
2603 
2604  vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2605 
2606  if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2607  cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2608  if (cinfo->btype == BT_PICASSO)
2609  data += 0xfff;
2610  *red = vga_r(cinfo->regbase, data);
2611  *green = vga_r(cinfo->regbase, data);
2612  *blue = vga_r(cinfo->regbase, data);
2613  } else {
2614  *blue = vga_r(cinfo->regbase, data);
2615  *green = vga_r(cinfo->regbase, data);
2616  *red = vga_r(cinfo->regbase, data);
2617  }
2618 }
2619 #endif
2620 
2621 /*******************************************************************
2622  cirrusfb_WaitBLT()
2623 
2624  Wait for the BitBLT engine to complete a possible earlier job
2625 *********************************************************************/
2626 
2627 /* FIXME: use interrupts instead */
2628 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2629 {
2630  while (vga_rgfx(regbase, CL_GR31) & 0x08)
2631  cpu_relax();
2632 }
2633 
2634 /*******************************************************************
2635  cirrusfb_BitBLT()
2636 
2637  perform accelerated "scrolling"
2638 ********************************************************************/
2639 
2640 static void cirrusfb_set_blitter(u8 __iomem *regbase,
2641  u_short nwidth, u_short nheight,
2642  u_long nsrc, u_long ndest,
2643  u_short bltmode, u_short line_length)
2644 
2645 {
2646  /* pitch: set to line_length */
2647  /* dest pitch low */
2648  vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2649  /* dest pitch hi */
2650  vga_wgfx(regbase, CL_GR25, line_length >> 8);
2651  /* source pitch low */
2652  vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2653  /* source pitch hi */
2654  vga_wgfx(regbase, CL_GR27, line_length >> 8);
2655 
2656  /* BLT width: actual number of pixels - 1 */
2657  /* BLT width low */
2658  vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2659  /* BLT width hi */
2660  vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2661 
2662  /* BLT height: actual number of lines -1 */
2663  /* BLT height low */
2664  vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2665  /* BLT width hi */
2666  vga_wgfx(regbase, CL_GR23, nheight >> 8);
2667 
2668  /* BLT destination */
2669  /* BLT dest low */
2670  vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2671  /* BLT dest mid */
2672  vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2673  /* BLT dest hi */
2674  vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2675 
2676  /* BLT source */
2677  /* BLT src low */
2678  vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2679  /* BLT src mid */
2680  vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2681  /* BLT src hi */
2682  vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2683 
2684  /* BLT mode */
2685  vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
2686 
2687  /* BLT ROP: SrcCopy */
2688  vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2689 
2690  /* and finally: GO! */
2691  vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2692 }
2693 
2694 /*******************************************************************
2695  cirrusfb_BitBLT()
2696 
2697  perform accelerated "scrolling"
2698 ********************************************************************/
2699 
2700 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2701  u_short curx, u_short cury,
2702  u_short destx, u_short desty,
2704  u_short line_length)
2705 {
2706  u_short nwidth = width - 1;
2707  u_short nheight = height - 1;
2708  u_long nsrc, ndest;
2709  u_char bltmode;
2710 
2711  bltmode = 0x00;
2712  /* if source adr < dest addr, do the Blt backwards */
2713  if (cury <= desty) {
2714  if (cury == desty) {
2715  /* if src and dest are on the same line, check x */
2716  if (curx < destx)
2717  bltmode |= 0x01;
2718  } else
2719  bltmode |= 0x01;
2720  }
2721  /* standard case: forward blitting */
2722  nsrc = (cury * line_length) + curx;
2723  ndest = (desty * line_length) + destx;
2724  if (bltmode) {
2725  /* this means start addresses are at the end,
2726  * counting backwards
2727  */
2728  nsrc += nheight * line_length + nwidth;
2729  ndest += nheight * line_length + nwidth;
2730  }
2731 
2732  cirrusfb_WaitBLT(regbase);
2733 
2734  cirrusfb_set_blitter(regbase, nwidth, nheight,
2735  nsrc, ndest, bltmode, line_length);
2736 }
2737 
2738 /*******************************************************************
2739  cirrusfb_RectFill()
2740 
2741  perform accelerated rectangle fill
2742 ********************************************************************/
2743 
2744 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2745  u_short x, u_short y, u_short width, u_short height,
2746  u32 fg_color, u32 bg_color, u_short line_length,
2747  u_char blitmode)
2748 {
2749  u_long ndest = (y * line_length) + x;
2750  u_char op;
2751 
2752  cirrusfb_WaitBLT(regbase);
2753 
2754  /* This is a ColorExpand Blt, using the */
2755  /* same color for foreground and background */
2756  vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2757  vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2758 
2759  op = 0x80;
2760  if (bits_per_pixel >= 16) {
2761  vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2762  vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2763  op = 0x90;
2764  }
2765  if (bits_per_pixel >= 24) {
2766  vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2767  vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2768  op = 0xa0;
2769  }
2770  if (bits_per_pixel == 32) {
2771  vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2772  vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2773  op = 0xb0;
2774  }
2775  cirrusfb_set_blitter(regbase, width - 1, height - 1,
2776  0, ndest, op | blitmode, line_length);
2777 }
2778 
2779 /**************************************************************************
2780  * bestclock() - determine closest possible clock lower(?) than the
2781  * desired pixel clock
2782  **************************************************************************/
2783 static void bestclock(long freq, int *nom, int *den, int *div)
2784 {
2785  int n, d;
2786  long h, diff;
2787 
2788  assert(nom != NULL);
2789  assert(den != NULL);
2790  assert(div != NULL);
2791 
2792  *nom = 0;
2793  *den = 0;
2794  *div = 0;
2795 
2796  if (freq < 8000)
2797  freq = 8000;
2798 
2799  diff = freq;
2800 
2801  for (n = 32; n < 128; n++) {
2802  int s = 0;
2803 
2804  d = (14318 * n) / freq;
2805  if ((d >= 7) && (d <= 63)) {
2806  int temp = d;
2807 
2808  if (temp > 31) {
2809  s = 1;
2810  temp >>= 1;
2811  }
2812  h = ((14318 * n) / temp) >> s;
2813  h = h > freq ? h - freq : freq - h;
2814  if (h < diff) {
2815  diff = h;
2816  *nom = n;
2817  *den = temp;
2818  *div = s;
2819  }
2820  }
2821  d++;
2822  if ((d >= 7) && (d <= 63)) {
2823  if (d > 31) {
2824  s = 1;
2825  d >>= 1;
2826  }
2827  h = ((14318 * n) / d) >> s;
2828  h = h > freq ? h - freq : freq - h;
2829  if (h < diff) {
2830  diff = h;
2831  *nom = n;
2832  *den = d;
2833  *div = s;
2834  }
2835  }
2836  }
2837 }
2838 
2839 /* -------------------------------------------------------------------------
2840  *
2841  * debugging functions
2842  *
2843  * -------------------------------------------------------------------------
2844  */
2845 
2846 #ifdef CIRRUSFB_DEBUG
2847 
2859 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2860  caddr_t regbase,
2861  enum cirrusfb_dbg_reg_class reg_class, ...)
2862 {
2863  va_list list;
2864  unsigned char val = 0;
2865  unsigned reg;
2866  char *name;
2867 
2868  va_start(list, reg_class);
2869 
2870  name = va_arg(list, char *);
2871  while (name != NULL) {
2872  reg = va_arg(list, int);
2873 
2874  switch (reg_class) {
2875  case CRT:
2876  val = vga_rcrt(regbase, (unsigned char) reg);
2877  break;
2878  case SEQ:
2879  val = vga_rseq(regbase, (unsigned char) reg);
2880  break;
2881  default:
2882  /* should never occur */
2883  assert(false);
2884  break;
2885  }
2886 
2887  dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2888 
2889  name = va_arg(list, char *);
2890  }
2891 
2892  va_end(list);
2893 }
2894 
2905 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2906 {
2907  dev_dbg(info->device, "VGA CRTC register dump:\n");
2908 
2909  cirrusfb_dbg_print_regs(info, regbase, CRT,
2910  "CR00", 0x00,
2911  "CR01", 0x01,
2912  "CR02", 0x02,
2913  "CR03", 0x03,
2914  "CR04", 0x04,
2915  "CR05", 0x05,
2916  "CR06", 0x06,
2917  "CR07", 0x07,
2918  "CR08", 0x08,
2919  "CR09", 0x09,
2920  "CR0A", 0x0A,
2921  "CR0B", 0x0B,
2922  "CR0C", 0x0C,
2923  "CR0D", 0x0D,
2924  "CR0E", 0x0E,
2925  "CR0F", 0x0F,
2926  "CR10", 0x10,
2927  "CR11", 0x11,
2928  "CR12", 0x12,
2929  "CR13", 0x13,
2930  "CR14", 0x14,
2931  "CR15", 0x15,
2932  "CR16", 0x16,
2933  "CR17", 0x17,
2934  "CR18", 0x18,
2935  "CR22", 0x22,
2936  "CR24", 0x24,
2937  "CR26", 0x26,
2938  "CR2D", 0x2D,
2939  "CR2E", 0x2E,
2940  "CR2F", 0x2F,
2941  "CR30", 0x30,
2942  "CR31", 0x31,
2943  "CR32", 0x32,
2944  "CR33", 0x33,
2945  "CR34", 0x34,
2946  "CR35", 0x35,
2947  "CR36", 0x36,
2948  "CR37", 0x37,
2949  "CR38", 0x38,
2950  "CR39", 0x39,
2951  "CR3A", 0x3A,
2952  "CR3B", 0x3B,
2953  "CR3C", 0x3C,
2954  "CR3D", 0x3D,
2955  "CR3E", 0x3E,
2956  "CR3F", 0x3F,
2957  NULL);
2958 
2959  dev_dbg(info->device, "\n");
2960 
2961  dev_dbg(info->device, "VGA SEQ register dump:\n");
2962 
2963  cirrusfb_dbg_print_regs(info, regbase, SEQ,
2964  "SR00", 0x00,
2965  "SR01", 0x01,
2966  "SR02", 0x02,
2967  "SR03", 0x03,
2968  "SR04", 0x04,
2969  "SR08", 0x08,
2970  "SR09", 0x09,
2971  "SR0A", 0x0A,
2972  "SR0B", 0x0B,
2973  "SR0D", 0x0D,
2974  "SR10", 0x10,
2975  "SR11", 0x11,
2976  "SR12", 0x12,
2977  "SR13", 0x13,
2978  "SR14", 0x14,
2979  "SR15", 0x15,
2980  "SR16", 0x16,
2981  "SR17", 0x17,
2982  "SR18", 0x18,
2983  "SR19", 0x19,
2984  "SR1A", 0x1A,
2985  "SR1B", 0x1B,
2986  "SR1C", 0x1C,
2987  "SR1D", 0x1D,
2988  "SR1E", 0x1E,
2989  "SR1F", 0x1F,
2990  NULL);
2991 
2992  dev_dbg(info->device, "\n");
2993 }
2994 
2995 #endif /* CIRRUSFB_DEBUG */
2996