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