2 * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
4 * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
6 * Contributors (thanks, all!)
9 * Overhaul for Linux 2.6
12 * Major contributions; Motorola PowerStack (PPC and PCI) support,
13 * GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
16 * Excellent code review.
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
37 #define CIRRUSFB_VERSION "2.0-pre2"
39 #include <linux/module.h>
40 #include <linux/kernel.h>
41 #include <linux/errno.h>
42 #include <linux/string.h>
44 #include <linux/slab.h>
45 #include <linux/delay.h>
47 #include <linux/init.h>
48 #include <asm/pgtable.h>
51 #include <linux/zorro.h>
54 #include <linux/pci.h>
57 #include <asm/amigahw.h>
59 #ifdef CONFIG_PPC_PREP
60 #include <asm/machdep.h>
61 #define isPReP machine_is(prep)
66 #include <video/vga.h>
67 #include <video/cirrus.h>
69 /*****************************************************************
71 * debugging and utility macros
75 /* enable debug output? */
76 /* #define CIRRUSFB_DEBUG 1 */
78 /* disable runtime assertions? */
79 /* #define CIRRUSFB_NDEBUG */
83 #define DPRINTK(fmt, args...) \
84 printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
86 #define DPRINTK(fmt, args...)
89 /* debugging assertions */
90 #ifndef CIRRUSFB_NDEBUG
91 #define assert(expr) \
93 printk("Assertion failed! %s,%s,%s,line=%d\n", \
94 #expr, __FILE__, __func__, __LINE__); \
100 #define MB_ (1024 * 1024)
102 /*****************************************************************
104 * chipset information
115 BT_PICASSO4, /* GD5446 */
116 BT_ALPINE, /* GD543x/4x */
118 BT_LAGUNA, /* GD546x */
122 * per-board-type information, used for enumerating and abstracting
123 * chip-specific information
124 * NOTE: MUST be in the same order as enum cirrus_board in order to
125 * use direct indexing on this array
126 * NOTE: '__initdata' cannot be used as some of this info
127 * is required at runtime. Maybe separate into an init-only and
130 static const struct cirrusfb_board_info_rec {
131 char *name; /* ASCII name of chipset */
132 long maxclock[5]; /* maximum video clock */
133 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
134 bool init_sr07 : 1; /* init SR07 during init_vgachip() */
135 bool init_sr1f : 1; /* write SR1F during init_vgachip() */
136 /* construct bit 19 of screen start address */
137 bool scrn_start_bit19 : 1;
139 /* initial SR07 value, then for each mode */
141 unsigned char sr07_1bpp;
142 unsigned char sr07_1bpp_mux;
143 unsigned char sr07_8bpp;
144 unsigned char sr07_8bpp_mux;
146 unsigned char sr1f; /* SR1F VGA initial register value */
147 } cirrusfb_board_info[] = {
152 /* the SD64/P4 have a higher max. videoclock */
153 140000, 140000, 140000, 140000, 140000,
157 .scrn_start_bit19 = true,
164 .name = "CL Piccolo",
167 90000, 90000, 90000, 90000, 90000
171 .scrn_start_bit19 = false,
178 .name = "CL Picasso",
181 90000, 90000, 90000, 90000, 90000
185 .scrn_start_bit19 = false,
192 .name = "CL Spectrum",
195 90000, 90000, 90000, 90000, 90000
199 .scrn_start_bit19 = false,
206 .name = "CL Picasso4",
208 135100, 135100, 85500, 85500, 0
212 .scrn_start_bit19 = true,
221 /* for the GD5430. GD5446 can do more... */
222 85500, 85500, 50000, 28500, 0
226 .scrn_start_bit19 = true,
229 .sr07_1bpp_mux = 0xA7,
231 .sr07_8bpp_mux = 0xA7,
237 135100, 200000, 200000, 135100, 135100
241 .scrn_start_bit19 = true,
251 135100, 135100, 135100, 135100, 135100,
255 .scrn_start_bit19 = true,
260 #define CHIP(id, btype) \
261 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
263 static struct pci_device_id cirrusfb_pci_table[] = {
264 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
265 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
266 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
267 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
268 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
269 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
270 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
271 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
272 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
273 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
274 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
277 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
279 #endif /* CONFIG_PCI */
282 static const struct zorro_device_id cirrusfb_zorro_table[] = {
284 .id = ZORRO_PROD_HELFRICH_SD64_RAM,
285 .driver_data = BT_SD64,
287 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
288 .driver_data = BT_PICCOLO,
290 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
291 .driver_data = BT_PICASSO,
293 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
294 .driver_data = BT_SPECTRUM,
296 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
297 .driver_data = BT_PICASSO4,
302 static const struct {
305 } cirrusfb_zorro_table2[] = {
307 .id2 = ZORRO_PROD_HELFRICH_SD64_REG,
311 .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG,
315 .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
319 .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
327 #endif /* CONFIG_ZORRO */
329 struct cirrusfb_regs {
338 long HorizRes; /* The x resolution in pixel */
341 long HorizBlankStart;
346 long VertRes; /* the physical y resolution in scanlines */
355 #ifdef CIRRUSFB_DEBUG
356 enum cirrusfb_dbg_reg_class {
360 #endif /* CIRRUSFB_DEBUG */
362 /* info about board */
363 struct cirrusfb_info {
365 enum cirrus_board btype;
366 unsigned char SFR; /* Shadow of special function register */
368 struct cirrusfb_regs currentmode;
370 u32 pseudo_palette[16];
372 void (*unmap)(struct fb_info *info);
376 static char *mode_option __devinitdata = "640x480@60";
378 /****************************************************************************/
379 /**** BEGIN PROTOTYPES ******************************************************/
381 /*--- Interface used by the world ------------------------------------------*/
382 static int cirrusfb_init(void);
384 static int cirrusfb_setup(char *options);
387 static int cirrusfb_open(struct fb_info *info, int user);
388 static int cirrusfb_release(struct fb_info *info, int user);
389 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
390 unsigned blue, unsigned transp,
391 struct fb_info *info);
392 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
393 struct fb_info *info);
394 static int cirrusfb_set_par(struct fb_info *info);
395 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
396 struct fb_info *info);
397 static int cirrusfb_blank(int blank_mode, struct fb_info *info);
398 static void cirrusfb_fillrect(struct fb_info *info,
399 const struct fb_fillrect *region);
400 static void cirrusfb_copyarea(struct fb_info *info,
401 const struct fb_copyarea *area);
402 static void cirrusfb_imageblit(struct fb_info *info,
403 const struct fb_image *image);
405 /* function table of the above functions */
406 static struct fb_ops cirrusfb_ops = {
407 .owner = THIS_MODULE,
408 .fb_open = cirrusfb_open,
409 .fb_release = cirrusfb_release,
410 .fb_setcolreg = cirrusfb_setcolreg,
411 .fb_check_var = cirrusfb_check_var,
412 .fb_set_par = cirrusfb_set_par,
413 .fb_pan_display = cirrusfb_pan_display,
414 .fb_blank = cirrusfb_blank,
415 .fb_fillrect = cirrusfb_fillrect,
416 .fb_copyarea = cirrusfb_copyarea,
417 .fb_imageblit = cirrusfb_imageblit,
420 /*--- Hardware Specific Routines -------------------------------------------*/
421 static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
422 struct cirrusfb_regs *regs,
423 struct fb_info *info);
424 /*--- Internal routines ----------------------------------------------------*/
425 static void init_vgachip(struct fb_info *info);
426 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
427 static void WGen(const struct cirrusfb_info *cinfo,
428 int regnum, unsigned char val);
429 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
430 static void AttrOn(const struct cirrusfb_info *cinfo);
431 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
432 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
433 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
434 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
435 unsigned char red, unsigned char green, unsigned char blue);
437 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
438 unsigned char *red, unsigned char *green,
439 unsigned char *blue);
441 static void cirrusfb_WaitBLT(u8 __iomem *regbase);
442 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
443 u_short curx, u_short cury,
444 u_short destx, u_short desty,
445 u_short width, u_short height,
446 u_short line_length);
447 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
448 u_short x, u_short y,
449 u_short width, u_short height,
450 u_char color, u_short line_length);
452 static void bestclock(long freq, long *best,
453 long *nom, long *den,
454 long *div, long maxfreq);
456 #ifdef CIRRUSFB_DEBUG
457 static void cirrusfb_dump(void);
458 static void cirrusfb_dbg_reg_dump(caddr_t regbase);
459 static void cirrusfb_dbg_print_regs(caddr_t regbase,
460 enum cirrusfb_dbg_reg_class reg_class, ...);
461 static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
462 #endif /* CIRRUSFB_DEBUG */
464 /*** END PROTOTYPES ********************************************************/
465 /*****************************************************************************/
466 /*** BEGIN Interface Used by the World ***************************************/
468 static int opencount;
470 /*--- Open /dev/fbx ---------------------------------------------------------*/
471 static int cirrusfb_open(struct fb_info *info, int user)
473 if (opencount++ == 0)
474 switch_monitor(info->par, 1);
478 /*--- Close /dev/fbx --------------------------------------------------------*/
479 static int cirrusfb_release(struct fb_info *info, int user)
481 if (--opencount == 0)
482 switch_monitor(info->par, 0);
486 /**** END Interface used by the World *************************************/
487 /****************************************************************************/
488 /**** BEGIN Hardware specific Routines **************************************/
490 /* Get a good MCLK value */
491 static long cirrusfb_get_mclk(long freq, int bpp, long *div)
497 /* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
498 * Assume a 64-bit data path for now. The formula is:
499 * ((B * PCLK * 2)/W) * 1.2
500 * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
501 mclk = ((bpp / 8) * freq * 2) / 4;
502 mclk = (mclk * 12) / 10;
505 DPRINTK("Use MCLK of %ld kHz\n", mclk);
507 /* Calculate value for SR1F. Multiply by 2 so we can round up. */
508 mclk = ((mclk * 16) / 14318);
509 mclk = (mclk + 1) / 2;
510 DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
512 /* Determine if we should use MCLK instead of VCLK, and if so, what we
513 * should divide it by to get VCLK */
515 case 24751 ... 25249:
517 DPRINTK("Using VCLK = MCLK/2\n");
519 case 49501 ... 50499:
521 DPRINTK("Using VCLK = MCLK\n");
531 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
532 struct fb_info *info)
535 /* memory size in pixels */
536 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
538 switch (var->bits_per_pixel) {
541 break; /* 8 pixel per byte, only 1/4th of mem usable */
545 break; /* 1 pixel == 1 byte */
547 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
548 "color depth not supported.\n",
549 var->xres, var->yres, var->bits_per_pixel);
550 DPRINTK("EXIT - EINVAL error\n");
554 if (var->xres_virtual < var->xres)
555 var->xres_virtual = var->xres;
556 /* use highest possible virtual resolution */
557 if (var->yres_virtual == -1) {
558 var->yres_virtual = pixels / var->xres_virtual;
560 printk(KERN_INFO "cirrusfb: virtual resolution set to "
561 "maximum of %dx%d\n", var->xres_virtual,
564 if (var->yres_virtual < var->yres)
565 var->yres_virtual = var->yres;
567 if (var->xres_virtual * var->yres_virtual > pixels) {
568 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... "
569 "virtual resolution too high to fit into video memory!\n",
570 var->xres_virtual, var->yres_virtual,
571 var->bits_per_pixel);
572 DPRINTK("EXIT - EINVAL error\n");
577 if (var->xoffset < 0)
579 if (var->yoffset < 0)
582 /* truncate xoffset and yoffset to maximum if too high */
583 if (var->xoffset > var->xres_virtual - var->xres)
584 var->xoffset = var->xres_virtual - var->xres - 1;
585 if (var->yoffset > var->yres_virtual - var->yres)
586 var->yoffset = var->yres_virtual - var->yres - 1;
588 switch (var->bits_per_pixel) {
592 var->green = var->red;
593 var->blue = var->red;
599 var->green = var->red;
600 var->blue = var->red;
606 var->green.offset = -3;
607 var->blue.offset = 8;
609 var->red.offset = 10;
610 var->green.offset = 5;
611 var->blue.offset = 0;
614 var->green.length = 5;
615 var->blue.length = 5;
621 var->green.offset = 16;
622 var->blue.offset = 24;
624 var->red.offset = 16;
625 var->green.offset = 8;
626 var->blue.offset = 0;
629 var->green.length = 8;
630 var->blue.length = 8;
634 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
636 /* should never occur */
641 var->green.msb_right =
642 var->blue.msb_right =
645 var->transp.msb_right = 0;
648 if (var->vmode & FB_VMODE_DOUBLE)
650 else if (var->vmode & FB_VMODE_INTERLACED)
651 yres = (yres + 1) / 2;
654 printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; "
655 "special treatment required! (TODO)\n");
656 DPRINTK("EXIT - EINVAL error\n");
663 static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
664 struct cirrusfb_regs *regs,
665 struct fb_info *info)
669 int maxclockidx = var->bits_per_pixel >> 3;
670 struct cirrusfb_info *cinfo = info->par;
671 int xres, hfront, hsync, hback;
672 int yres, vfront, vsync, vback;
674 switch (var->bits_per_pixel) {
676 info->fix.line_length = var->xres_virtual / 8;
677 info->fix.visual = FB_VISUAL_MONO10;
681 info->fix.line_length = var->xres_virtual;
682 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
687 info->fix.line_length = var->xres_virtual * maxclockidx;
688 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
692 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
694 /* should never occur */
698 info->fix.type = FB_TYPE_PACKED_PIXELS;
700 /* convert from ps to kHz */
701 freq = PICOS2KHZ(var->pixclock);
703 DPRINTK("desired pixclock: %ld kHz\n", freq);
705 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
706 regs->multiplexing = 0;
708 /* If the frequency is greater than we can support, we might be able
709 * to use multiplexing for the video mode */
710 if (freq > maxclock) {
711 switch (cinfo->btype) {
714 regs->multiplexing = 1;
718 printk(KERN_ERR "cirrusfb: Frequency greater "
719 "than maxclock (%ld kHz)\n", maxclock);
720 DPRINTK("EXIT - return -EINVAL\n");
725 /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
726 * the VCLK is double the pixel clock. */
727 switch (var->bits_per_pixel) {
730 if (regs->HorizRes <= 800)
731 /* Xbh has this type of clock for 32-bit */
737 bestclock(freq, ®s->freq, ®s->nom, ®s->den, ®s->div,
739 regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
743 hfront = var->right_margin;
744 hsync = var->hsync_len;
745 hback = var->left_margin;
748 vfront = var->lower_margin;
749 vsync = var->vsync_len;
750 vback = var->upper_margin;
752 if (var->vmode & FB_VMODE_DOUBLE) {
757 } else if (var->vmode & FB_VMODE_INTERLACED) {
758 yres = (yres + 1) / 2;
759 vfront = (vfront + 1) / 2;
760 vsync = (vsync + 1) / 2;
761 vback = (vback + 1) / 2;
763 regs->HorizRes = xres;
764 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
765 regs->HorizDispEnd = xres / 8 - 1;
766 regs->HorizBlankStart = xres / 8;
767 /* does not count with "-5" */
768 regs->HorizBlankEnd = regs->HorizTotal + 5;
769 regs->HorizSyncStart = (xres + hfront) / 8 + 1;
770 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
772 regs->VertRes = yres;
773 regs->VertTotal = yres + vfront + vsync + vback - 2;
774 regs->VertDispEnd = yres - 1;
775 regs->VertBlankStart = yres;
776 regs->VertBlankEnd = regs->VertTotal;
777 regs->VertSyncStart = yres + vfront - 1;
778 regs->VertSyncEnd = yres + vfront + vsync - 1;
780 if (regs->VertRes >= 1024) {
781 regs->VertTotal /= 2;
782 regs->VertSyncStart /= 2;
783 regs->VertSyncEnd /= 2;
784 regs->VertDispEnd /= 2;
786 if (regs->multiplexing) {
787 regs->HorizTotal /= 2;
788 regs->HorizSyncStart /= 2;
789 regs->HorizSyncEnd /= 2;
790 regs->HorizDispEnd /= 2;
796 static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
799 assert(cinfo != NULL);
803 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
804 vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
805 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
806 } else if (div == 1) {
808 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
809 vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
810 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
812 vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
816 /*************************************************************************
817 cirrusfb_set_par_foo()
819 actually writes the values for a new video mode into the hardware,
820 **************************************************************************/
821 static int cirrusfb_set_par_foo(struct fb_info *info)
823 struct cirrusfb_info *cinfo = info->par;
824 struct fb_var_screeninfo *var = &info->var;
825 struct cirrusfb_regs regs;
826 u8 __iomem *regbase = cinfo->regbase;
829 const struct cirrusfb_board_info_rec *bi;
832 DPRINTK("Requested mode: %dx%dx%d\n",
833 var->xres, var->yres, var->bits_per_pixel);
834 DPRINTK("pixclock: %d\n", var->pixclock);
838 err = cirrusfb_decode_var(var, ®s, info);
840 /* should never happen */
841 DPRINTK("mode change aborted. invalid var.\n");
845 bi = &cirrusfb_board_info[cinfo->btype];
847 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
848 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
850 /* if debugging is enabled, all parameters get output before writing */
851 DPRINTK("CRT0: %ld\n", regs.HorizTotal);
852 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
854 DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
855 vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
857 DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
858 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
860 /* + 128: Compatible read */
861 DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
862 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
863 128 + (regs.HorizBlankEnd % 32));
865 DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
866 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
868 tmp = regs.HorizSyncEnd % 32;
869 if (regs.HorizBlankEnd & 32)
871 DPRINTK("CRT5: %d\n", tmp);
872 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
874 DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
875 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
877 tmp = 16; /* LineCompare bit #9 */
878 if (regs.VertTotal & 256)
880 if (regs.VertDispEnd & 256)
882 if (regs.VertSyncStart & 256)
884 if (regs.VertBlankStart & 256)
886 if (regs.VertTotal & 512)
888 if (regs.VertDispEnd & 512)
890 if (regs.VertSyncStart & 512)
892 DPRINTK("CRT7: %d\n", tmp);
893 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
895 tmp = 0x40; /* LineCompare bit #8 */
896 if (regs.VertBlankStart & 512)
898 if (var->vmode & FB_VMODE_DOUBLE)
900 DPRINTK("CRT9: %d\n", tmp);
901 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
903 DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
904 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
906 DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
907 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
909 DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
910 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
912 DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
913 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
915 DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
916 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
918 DPRINTK("CRT18: 0xff\n");
919 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
922 if (var->vmode & FB_VMODE_INTERLACED)
924 if (regs.HorizBlankEnd & 64)
926 if (regs.HorizBlankEnd & 128)
928 if (regs.VertBlankEnd & 256)
930 if (regs.VertBlankEnd & 512)
933 DPRINTK("CRT1a: %d\n", tmp);
934 vga_wcrt(regbase, CL_CRT1A, tmp);
937 /* hardware RefClock: 14.31818 MHz */
938 /* formula: VClk = (OSC * N) / (D * (1+P)) */
939 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
941 vga_wseq(regbase, CL_SEQRB, regs.nom);
946 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
947 if ((cinfo->btype == BT_SD64) ||
948 (cinfo->btype == BT_ALPINE) ||
949 (cinfo->btype == BT_GD5480))
952 DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
953 vga_wseq(regbase, CL_SEQR1B, tmp);
955 if (regs.VertRes >= 1024)
957 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
959 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
960 * address wrap, no compat. */
961 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
963 /* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
964 * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
966 /* don't know if it would hurt to also program this if no interlaced */
967 /* mode is used, but I feel better this way.. :-) */
968 if (var->vmode & FB_VMODE_INTERLACED)
969 vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
971 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
973 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
975 /* adjust horizontal/vertical sync type (low/high) */
976 /* enable display memory & CRTC I/O address for color mode */
978 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
980 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
982 WGen(cinfo, VGA_MIS_W, tmp);
984 /* Screen A Preset Row-Scan register */
985 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
986 /* text cursor on and start line */
987 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
988 /* text cursor end line */
989 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
991 /******************************************************
997 /* programming for different color depths */
998 if (var->bits_per_pixel == 1) {
999 DPRINTK("cirrusfb: preparing for 1 bit deep display\n");
1000 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
1003 switch (cinfo->btype) {
1011 DPRINTK(" (for GD54xx)\n");
1012 vga_wseq(regbase, CL_SEQR7,
1014 bi->sr07_1bpp_mux : bi->sr07_1bpp);
1018 DPRINTK(" (for GD546x)\n");
1019 vga_wseq(regbase, CL_SEQR7,
1020 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1024 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1028 /* Extended Sequencer Mode */
1029 switch (cinfo->btype) {
1031 /* setting the SEQRF on SD64 is not necessary
1032 * (only during init)
1034 DPRINTK("(for SD64)\n");
1036 vga_wseq(regbase, CL_SEQR1F, 0x1a);
1041 DPRINTK("(for Piccolo/Spectrum)\n");
1042 /* ### ueberall 0x22? */
1043 /* ##vorher 1c MCLK select */
1044 vga_wseq(regbase, CL_SEQR1F, 0x22);
1045 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
1046 vga_wseq(regbase, CL_SEQRF, 0xb0);
1050 DPRINTK("(for Picasso)\n");
1051 /* ##vorher 22 MCLK select */
1052 vga_wseq(regbase, CL_SEQR1F, 0x22);
1053 /* ## vorher d0 avoid FIFO underruns..? */
1054 vga_wseq(regbase, CL_SEQRF, 0xd0);
1061 DPRINTK(" (for GD54xx)\n");
1066 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1070 /* pixel mask: pass-through for first plane */
1071 WGen(cinfo, VGA_PEL_MSK, 0x01);
1072 if (regs.multiplexing)
1073 /* hidden dac reg: 1280x1024 */
1076 /* hidden dac: nothing */
1078 /* memory mode: odd/even, ext. memory */
1079 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1080 /* plane mask: only write to first plane */
1081 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1082 offset = var->xres_virtual / 16;
1085 /******************************************************
1091 else if (var->bits_per_pixel == 8) {
1092 DPRINTK("cirrusfb: preparing for 8 bit deep display\n");
1093 switch (cinfo->btype) {
1101 DPRINTK(" (for GD54xx)\n");
1102 vga_wseq(regbase, CL_SEQR7,
1104 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1108 DPRINTK(" (for GD546x)\n");
1109 vga_wseq(regbase, CL_SEQR7,
1110 vga_rseq(regbase, CL_SEQR7) | 0x01);
1114 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1118 switch (cinfo->btype) {
1121 vga_wseq(regbase, CL_SEQR1F, 0x1d);
1127 /* ### vorher 1c MCLK select */
1128 vga_wseq(regbase, CL_SEQR1F, 0x22);
1129 /* Fast Page-Mode writes */
1130 vga_wseq(regbase, CL_SEQRF, 0xb0);
1135 /* ### INCOMPLETE!! */
1136 vga_wseq(regbase, CL_SEQRF, 0xb8);
1138 /* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1142 DPRINTK(" (for GD543x)\n");
1143 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1144 /* We already set SRF and SR1F */
1149 DPRINTK(" (for GD54xx)\n");
1154 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1158 /* mode register: 256 color mode */
1159 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1160 /* pixel mask: pass-through all planes */
1161 WGen(cinfo, VGA_PEL_MSK, 0xff);
1162 if (regs.multiplexing)
1163 /* hidden dac reg: 1280x1024 */
1166 /* hidden dac: nothing */
1168 /* memory mode: chain4, ext. memory */
1169 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1170 /* plane mask: enable writing to all 4 planes */
1171 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1172 offset = var->xres_virtual / 8;
1175 /******************************************************
1181 else if (var->bits_per_pixel == 16) {
1182 DPRINTK("cirrusfb: preparing for 16 bit deep display\n");
1183 switch (cinfo->btype) {
1185 /* Extended Sequencer Mode: 256c col. mode */
1186 vga_wseq(regbase, CL_SEQR7, 0xf7);
1188 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1193 vga_wseq(regbase, CL_SEQR7, 0x87);
1194 /* Fast Page-Mode writes */
1195 vga_wseq(regbase, CL_SEQRF, 0xb0);
1197 vga_wseq(regbase, CL_SEQR1F, 0x22);
1201 vga_wseq(regbase, CL_SEQR7, 0x27);
1202 /* Fast Page-Mode writes */
1203 vga_wseq(regbase, CL_SEQRF, 0xb0);
1205 vga_wseq(regbase, CL_SEQR1F, 0x22);
1209 vga_wseq(regbase, CL_SEQR7, 0x27);
1210 /* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1214 DPRINTK(" (for GD543x)\n");
1215 if (regs.HorizRes >= 1024)
1216 vga_wseq(regbase, CL_SEQR7, 0xa7);
1218 vga_wseq(regbase, CL_SEQR7, 0xa3);
1219 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1223 DPRINTK(" (for GD5480)\n");
1224 vga_wseq(regbase, CL_SEQR7, 0x17);
1225 /* We already set SRF and SR1F */
1229 DPRINTK(" (for GD546x)\n");
1230 vga_wseq(regbase, CL_SEQR7,
1231 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1235 printk(KERN_WARNING "CIRRUSFB: unknown Board\n");
1239 /* mode register: 256 color mode */
1240 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1241 /* pixel mask: pass-through all planes */
1242 WGen(cinfo, VGA_PEL_MSK, 0xff);
1244 WHDR(cinfo, 0xc0); /* Copy Xbh */
1245 #elif defined(CONFIG_ZORRO)
1246 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1247 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1249 /* memory mode: chain4, ext. memory */
1250 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1251 /* plane mask: enable writing to all 4 planes */
1252 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1253 offset = var->xres_virtual / 4;
1256 /******************************************************
1262 else if (var->bits_per_pixel == 32) {
1263 DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
1264 switch (cinfo->btype) {
1266 /* Extended Sequencer Mode: 256c col. mode */
1267 vga_wseq(regbase, CL_SEQR7, 0xf9);
1269 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1274 vga_wseq(regbase, CL_SEQR7, 0x85);
1275 /* Fast Page-Mode writes */
1276 vga_wseq(regbase, CL_SEQRF, 0xb0);
1278 vga_wseq(regbase, CL_SEQR1F, 0x22);
1282 vga_wseq(regbase, CL_SEQR7, 0x25);
1283 /* Fast Page-Mode writes */
1284 vga_wseq(regbase, CL_SEQRF, 0xb0);
1286 vga_wseq(regbase, CL_SEQR1F, 0x22);
1290 vga_wseq(regbase, CL_SEQR7, 0x25);
1291 /* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1295 DPRINTK(" (for GD543x)\n");
1296 vga_wseq(regbase, CL_SEQR7, 0xa9);
1297 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1301 DPRINTK(" (for GD5480)\n");
1302 vga_wseq(regbase, CL_SEQR7, 0x19);
1303 /* We already set SRF and SR1F */
1307 DPRINTK(" (for GD546x)\n");
1308 vga_wseq(regbase, CL_SEQR7,
1309 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1313 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1317 /* mode register: 256 color mode */
1318 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1319 /* pixel mask: pass-through all planes */
1320 WGen(cinfo, VGA_PEL_MSK, 0xff);
1321 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1323 /* memory mode: chain4, ext. memory */
1324 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1325 /* plane mask: enable writing to all 4 planes */
1326 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1327 offset = var->xres_virtual / 4;
1330 /******************************************************
1332 * unknown/unsupported bpp
1337 printk(KERN_ERR "cirrusfb: What's this?? "
1338 " requested color depth == %d.\n",
1339 var->bits_per_pixel);
1341 vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
1344 tmp |= 0x10; /* offset overflow bit */
1346 /* screen start addr #16-18, fastpagemode cycles */
1347 vga_wcrt(regbase, CL_CRT1B, tmp);
1349 if (cinfo->btype == BT_SD64 ||
1350 cinfo->btype == BT_PICASSO4 ||
1351 cinfo->btype == BT_ALPINE ||
1352 cinfo->btype == BT_GD5480)
1353 /* screen start address bit 19 */
1354 vga_wcrt(regbase, CL_CRT1D, 0x00);
1356 /* text cursor location high */
1357 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
1358 /* text cursor location low */
1359 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
1360 /* underline row scanline = at very bottom */
1361 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
1363 /* controller mode */
1364 vga_wattr(regbase, VGA_ATC_MODE, 1);
1365 /* overscan (border) color */
1366 vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
1367 /* color plane enable */
1368 vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
1370 vga_wattr(regbase, CL_AR33, 0);
1372 vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1374 /* [ EGS: SetOffset(); ] */
1375 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1378 /* set/reset register */
1379 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
1380 /* set/reset enable */
1381 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
1383 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
1385 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1386 /* read map select */
1387 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1388 /* miscellaneous register */
1389 vga_wgfx(regbase, VGA_GFX_MISC, 1);
1390 /* color don't care */
1391 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1393 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1395 /* graphics cursor attributes: nothing special */
1396 vga_wseq(regbase, CL_SEQR12, 0x0);
1398 /* finally, turn on everything - turn off "FullBandwidth" bit */
1399 /* also, set "DotClock%2" bit where requested */
1402 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1403 if (var->vmode & FB_VMODE_CLOCK_HALVE)
1407 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1408 DPRINTK("CL_SEQR1: %d\n", tmp);
1410 cinfo->currentmode = regs;
1412 /* pan to requested offset */
1413 cirrusfb_pan_display(var, info);
1415 #ifdef CIRRUSFB_DEBUG
1423 /* for some reason incomprehensible to me, cirrusfb requires that you write
1424 * the registers twice for the settings to take..grr. -dte */
1425 static int cirrusfb_set_par(struct fb_info *info)
1427 cirrusfb_set_par_foo(info);
1428 return cirrusfb_set_par_foo(info);
1431 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1432 unsigned blue, unsigned transp,
1433 struct fb_info *info)
1435 struct cirrusfb_info *cinfo = info->par;
1440 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1442 red >>= (16 - info->var.red.length);
1443 green >>= (16 - info->var.green.length);
1444 blue >>= (16 - info->var.blue.length);
1448 v = (red << info->var.red.offset) |
1449 (green << info->var.green.offset) |
1450 (blue << info->var.blue.offset);
1452 cinfo->pseudo_palette[regno] = v;
1456 if (info->var.bits_per_pixel == 8)
1457 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1463 /*************************************************************************
1464 cirrusfb_pan_display()
1466 performs display panning - provided hardware permits this
1467 **************************************************************************/
1468 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1469 struct fb_info *info)
1474 unsigned char tmp = 0, tmp2 = 0, xpix;
1475 struct cirrusfb_info *cinfo = info->par;
1478 DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1480 /* no range checks for xoffset and yoffset, */
1481 /* as fb_pan_display has already done this */
1482 if (var->vmode & FB_VMODE_YWRAP)
1485 info->var.xoffset = var->xoffset;
1486 info->var.yoffset = var->yoffset;
1488 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1489 yoffset = var->yoffset;
1491 base = yoffset * info->fix.line_length + xoffset;
1493 if (info->var.bits_per_pixel == 1) {
1494 /* base is already correct */
1495 xpix = (unsigned char) (var->xoffset % 8);
1498 xpix = (unsigned char) ((xoffset % 4) * 2);
1501 cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
1503 /* lower 8 + 8 bits of screen start address */
1504 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
1505 (unsigned char) (base & 0xff));
1506 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1507 (unsigned char) (base >> 8));
1509 /* construct bits 16, 17 and 18 of screen start address */
1517 /* 0xf2 is %11110010, exclude tmp bits */
1518 tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
1519 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
1521 /* construct bit 19 of screen start address */
1522 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1523 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
1525 /* write pixel panning value to AR33; this does not quite work in 8bpp
1527 * ### Piccolo..? Will this work?
1529 if (info->var.bits_per_pixel == 1)
1530 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1532 cirrusfb_WaitBLT(cinfo->regbase);
1538 static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1541 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1542 * then the caller blanks by setting the CLUT (Color Look Up Table)
1543 * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1544 * failed due to e.g. a video mode which doesn't support it.
1545 * Implements VESA suspend and powerdown modes on hardware that
1546 * supports disabling hsync/vsync:
1547 * blank_mode == 2: suspend vsync
1548 * blank_mode == 3: suspend hsync
1549 * blank_mode == 4: powerdown
1552 struct cirrusfb_info *cinfo = info->par;
1553 int current_mode = cinfo->blank_mode;
1555 DPRINTK("ENTER, blank mode = %d\n", blank_mode);
1557 if (info->state != FBINFO_STATE_RUNNING ||
1558 current_mode == blank_mode) {
1559 DPRINTK("EXIT, returning 0\n");
1564 if (current_mode == FB_BLANK_NORMAL ||
1565 current_mode == FB_BLANK_UNBLANK) {
1566 /* unblank the screen */
1567 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1568 /* clear "FullBandwidth" bit */
1569 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
1570 /* and undo VESA suspend trickery */
1571 vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
1575 if (blank_mode > FB_BLANK_NORMAL) {
1576 /* blank the screen */
1577 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1578 /* set "FullBandwidth" bit */
1579 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
1582 switch (blank_mode) {
1583 case FB_BLANK_UNBLANK:
1584 case FB_BLANK_NORMAL:
1586 case FB_BLANK_VSYNC_SUSPEND:
1587 vga_wgfx(cinfo->regbase, CL_GRE, 0x04);
1589 case FB_BLANK_HSYNC_SUSPEND:
1590 vga_wgfx(cinfo->regbase, CL_GRE, 0x02);
1592 case FB_BLANK_POWERDOWN:
1593 vga_wgfx(cinfo->regbase, CL_GRE, 0x06);
1596 DPRINTK("EXIT, returning 1\n");
1600 cinfo->blank_mode = blank_mode;
1601 DPRINTK("EXIT, returning 0\n");
1603 /* Let fbcon do a soft blank for us */
1604 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1606 /**** END Hardware specific Routines **************************************/
1607 /****************************************************************************/
1608 /**** BEGIN Internal Routines ***********************************************/
1610 static void init_vgachip(struct fb_info *info)
1612 struct cirrusfb_info *cinfo = info->par;
1613 const struct cirrusfb_board_info_rec *bi;
1617 assert(cinfo != NULL);
1619 bi = &cirrusfb_board_info[cinfo->btype];
1621 /* reset board globally */
1622 switch (cinfo->btype) {
1641 /* disable flickerfixer */
1642 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1644 /* from Klaus' NetBSD driver: */
1645 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1646 /* put blitter into 542x compat */
1647 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1649 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1653 /* from Klaus' NetBSD driver: */
1654 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1658 /* Nothing to do to reset the board. */
1662 printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");
1666 /* make sure RAM size set by this point */
1667 assert(info->screen_size > 0);
1669 /* the P4 is not fully initialized here; I rely on it having been */
1670 /* inited under AmigaOS already, which seems to work just fine */
1671 /* (Klaus advised to do it this way) */
1673 if (cinfo->btype != BT_PICASSO4) {
1674 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1675 WGen(cinfo, CL_POS102, 0x01);
1676 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1678 if (cinfo->btype != BT_SD64)
1679 WGen(cinfo, CL_VSSM2, 0x01);
1681 /* reset sequencer logic */
1682 vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
1684 /* FullBandwidth (video off) and 8/9 dot clock */
1685 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1686 /* polarity (-/-), disable access to display memory,
1687 * VGA_CRTC_START_HI base address: color
1689 WGen(cinfo, VGA_MIS_W, 0xc1);
1691 /* "magic cookie" - doesn't make any sense to me.. */
1692 /* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1693 /* unlock all extension registers */
1694 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1697 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1699 switch (cinfo->btype) {
1701 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1706 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1709 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1710 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1714 /* plane mask: nothing */
1715 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1716 /* character map select: doesn't even matter in gx mode */
1717 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1718 /* memory mode: chain-4, no odd/even, ext. memory */
1719 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
1721 /* controller-internal base address of video memory */
1723 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1725 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1726 /* EEPROM control: shouldn't be necessary to write to this at all.. */
1728 /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1729 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1730 /* graphics cursor Y position (..."... ) */
1731 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1732 /* graphics cursor attributes */
1733 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1734 /* graphics cursor pattern address */
1735 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1737 /* writing these on a P4 might give problems.. */
1738 if (cinfo->btype != BT_PICASSO4) {
1739 /* configuration readback and ext. color */
1740 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1741 /* signature generator */
1742 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1745 /* MCLK select etc. */
1747 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1749 /* Screen A preset row scan: none */
1750 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1751 /* Text cursor start: disable text cursor */
1752 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1753 /* Text cursor end: - */
1754 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1755 /* Screen start address high: 0 */
1756 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1757 /* Screen start address low: 0 */
1758 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1759 /* text cursor location high: 0 */
1760 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1761 /* text cursor location low: 0 */
1762 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1764 /* Underline Row scanline: - */
1765 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1766 /* mode control: timing enable, byte mode, no compat modes */
1767 vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1768 /* Line Compare: not needed */
1769 vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1770 /* ### add 0x40 for text modes with > 30 MHz pixclock */
1771 /* ext. display controls: ext.adr. wrap */
1772 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1774 /* Set/Reset registes: - */
1775 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1776 /* Set/Reset enable: - */
1777 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1778 /* Color Compare: - */
1779 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1780 /* Data Rotate: - */
1781 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1782 /* Read Map Select: - */
1783 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1784 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1785 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1786 /* Miscellaneous: memory map base address, graphics mode */
1787 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1788 /* Color Don't care: involve all planes */
1789 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1790 /* Bit Mask: no mask at all */
1791 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1792 if (cinfo->btype == BT_ALPINE)
1793 /* (5434 can't have bit 3 set for bitblt) */
1794 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1796 /* Graphics controller mode extensions: finer granularity,
1797 * 8byte data latches
1799 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1801 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1802 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1803 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1804 /* Background color byte 1: - */
1805 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1806 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1808 /* Attribute Controller palette registers: "identity mapping" */
1809 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1810 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1811 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1812 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1813 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1814 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1815 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1816 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1817 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1818 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1819 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1820 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1821 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1822 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1823 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1824 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1826 /* Attribute Controller mode: graphics mode */
1827 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1828 /* Overscan color reg.: reg. 0 */
1829 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1830 /* Color Plane enable: Enable all 4 planes */
1831 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1832 /* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1833 /* Color Select: - */
1834 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1836 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1838 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1839 /* polarity (-/-), enable display mem,
1840 * VGA_CRTC_START_HI i/o base = color
1842 WGen(cinfo, VGA_MIS_W, 0xc3);
1844 /* BLT Start/status: Blitter reset */
1845 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1846 /* - " - : "end-of-reset" */
1847 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1850 WHDR(cinfo, 0); /* Hidden DAC register: - */
1856 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1858 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1859 static int IsOn = 0; /* XXX not ok for multiple boards */
1863 if (cinfo->btype == BT_PICASSO4)
1864 return; /* nothing to switch */
1865 if (cinfo->btype == BT_ALPINE)
1866 return; /* nothing to switch */
1867 if (cinfo->btype == BT_GD5480)
1868 return; /* nothing to switch */
1869 if (cinfo->btype == BT_PICASSO) {
1870 if ((on && !IsOn) || (!on && IsOn))
1877 switch (cinfo->btype) {
1879 WSFR(cinfo, cinfo->SFR | 0x21);
1882 WSFR(cinfo, cinfo->SFR | 0x28);
1887 default: /* do nothing */ break;
1890 switch (cinfo->btype) {
1892 WSFR(cinfo, cinfo->SFR & 0xde);
1895 WSFR(cinfo, cinfo->SFR & 0xd7);
1900 default: /* do nothing */ break;
1905 #endif /* CONFIG_ZORRO */
1908 /******************************************/
1909 /* Linux 2.6-style accelerated functions */
1910 /******************************************/
1912 static void cirrusfb_fillrect(struct fb_info *info,
1913 const struct fb_fillrect *region)
1915 struct fb_fillrect modded;
1917 struct cirrusfb_info *cinfo = info->par;
1918 int m = info->var.bits_per_pixel;
1919 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1920 cinfo->pseudo_palette[region->color] : region->color;
1922 if (info->state != FBINFO_STATE_RUNNING)
1924 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1925 cfb_fillrect(info, region);
1929 vxres = info->var.xres_virtual;
1930 vyres = info->var.yres_virtual;
1932 memcpy(&modded, region, sizeof(struct fb_fillrect));
1934 if (!modded.width || !modded.height ||
1935 modded.dx >= vxres || modded.dy >= vyres)
1938 if (modded.dx + modded.width > vxres)
1939 modded.width = vxres - modded.dx;
1940 if (modded.dy + modded.height > vyres)
1941 modded.height = vyres - modded.dy;
1943 cirrusfb_RectFill(cinfo->regbase,
1944 info->var.bits_per_pixel,
1945 (region->dx * m) / 8, region->dy,
1946 (region->width * m) / 8, region->height,
1948 info->fix.line_length);
1951 static void cirrusfb_copyarea(struct fb_info *info,
1952 const struct fb_copyarea *area)
1954 struct fb_copyarea modded;
1956 struct cirrusfb_info *cinfo = info->par;
1957 int m = info->var.bits_per_pixel;
1959 if (info->state != FBINFO_STATE_RUNNING)
1961 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1962 cfb_copyarea(info, area);
1966 vxres = info->var.xres_virtual;
1967 vyres = info->var.yres_virtual;
1968 memcpy(&modded, area, sizeof(struct fb_copyarea));
1970 if (!modded.width || !modded.height ||
1971 modded.sx >= vxres || modded.sy >= vyres ||
1972 modded.dx >= vxres || modded.dy >= vyres)
1975 if (modded.sx + modded.width > vxres)
1976 modded.width = vxres - modded.sx;
1977 if (modded.dx + modded.width > vxres)
1978 modded.width = vxres - modded.dx;
1979 if (modded.sy + modded.height > vyres)
1980 modded.height = vyres - modded.sy;
1981 if (modded.dy + modded.height > vyres)
1982 modded.height = vyres - modded.dy;
1984 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1985 (area->sx * m) / 8, area->sy,
1986 (area->dx * m) / 8, area->dy,
1987 (area->width * m) / 8, area->height,
1988 info->fix.line_length);
1992 static void cirrusfb_imageblit(struct fb_info *info,
1993 const struct fb_image *image)
1995 struct cirrusfb_info *cinfo = info->par;
1997 cirrusfb_WaitBLT(cinfo->regbase);
1998 cfb_imageblit(info, image);
2001 #ifdef CONFIG_PPC_PREP
2002 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
2003 #define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
2004 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
2008 *display = PREP_VIDEO_BASE;
2009 *registers = (unsigned long) PREP_IO_BASE;
2014 #endif /* CONFIG_PPC_PREP */
2017 static int release_io_ports;
2019 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
2020 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
2021 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
2023 static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
2030 SRF = vga_rseq(regbase, CL_SEQRF);
2031 switch ((SRF & 0x18)) {
2038 /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
2045 printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");
2049 /* If DRAM bank switching is enabled, there must be twice as much
2050 * memory installed. (4MB on the 5434)
2054 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
2060 static void get_pci_addrs(const struct pci_dev *pdev,
2061 unsigned long *display, unsigned long *registers)
2063 assert(pdev != NULL);
2064 assert(display != NULL);
2065 assert(registers != NULL);
2072 /* This is a best-guess for now */
2074 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
2075 *display = pci_resource_start(pdev, 1);
2076 *registers = pci_resource_start(pdev, 0);
2078 *display = pci_resource_start(pdev, 0);
2079 *registers = pci_resource_start(pdev, 1);
2082 assert(*display != 0);
2087 static void cirrusfb_pci_unmap(struct fb_info *info)
2089 struct pci_dev *pdev = to_pci_dev(info->device);
2091 iounmap(info->screen_base);
2092 #if 0 /* if system didn't claim this region, we would... */
2093 release_mem_region(0xA0000, 65535);
2095 if (release_io_ports)
2096 release_region(0x3C0, 32);
2097 pci_release_regions(pdev);
2099 #endif /* CONFIG_PCI */
2102 static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
2104 struct cirrusfb_info *cinfo = info->par;
2105 struct zorro_dev *zdev = to_zorro_dev(info->device);
2107 zorro_release_device(zdev);
2109 if (cinfo->btype == BT_PICASSO4) {
2110 cinfo->regbase -= 0x600000;
2111 iounmap((void *)cinfo->regbase);
2112 iounmap(info->screen_base);
2114 if (zorro_resource_start(zdev) > 0x01000000)
2115 iounmap(info->screen_base);
2118 #endif /* CONFIG_ZORRO */
2120 static int cirrusfb_set_fbinfo(struct fb_info *info)
2122 struct cirrusfb_info *cinfo = info->par;
2123 struct fb_var_screeninfo *var = &info->var;
2125 info->pseudo_palette = cinfo->pseudo_palette;
2126 info->flags = FBINFO_DEFAULT
2127 | FBINFO_HWACCEL_XPAN
2128 | FBINFO_HWACCEL_YPAN
2129 | FBINFO_HWACCEL_FILLRECT
2130 | FBINFO_HWACCEL_COPYAREA;
2132 info->flags |= FBINFO_HWACCEL_DISABLED;
2133 info->fbops = &cirrusfb_ops;
2134 if (cinfo->btype == BT_GD5480) {
2135 if (var->bits_per_pixel == 16)
2136 info->screen_base += 1 * MB_;
2137 if (var->bits_per_pixel == 32)
2138 info->screen_base += 2 * MB_;
2141 /* Fill fix common fields */
2142 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2143 sizeof(info->fix.id));
2145 /* monochrome: only 1 memory plane */
2146 /* 8 bit and above: Use whole memory area */
2147 info->fix.smem_len = info->screen_size;
2148 if (var->bits_per_pixel == 1)
2149 info->fix.smem_len /= 4;
2150 info->fix.type_aux = 0;
2151 info->fix.xpanstep = 1;
2152 info->fix.ypanstep = 1;
2153 info->fix.ywrapstep = 0;
2155 /* FIXME: map region at 0xB8000 if available, fill in here */
2156 info->fix.mmio_len = 0;
2157 info->fix.accel = FB_ACCEL_NONE;
2159 fb_alloc_cmap(&info->cmap, 256, 0);
2164 static int cirrusfb_register(struct fb_info *info)
2166 struct cirrusfb_info *cinfo = info->par;
2168 enum cirrus_board btype;
2172 printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
2173 "graphic boards, v" CIRRUSFB_VERSION "\n");
2175 btype = cinfo->btype;
2178 assert(btype != BT_NONE);
2180 /* set all the vital stuff */
2181 cirrusfb_set_fbinfo(info);
2183 DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
2185 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2187 DPRINTK("wrong initial video mode\n");
2189 goto err_dealloc_cmap;
2192 info->var.activate = FB_ACTIVATE_NOW;
2194 err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
2196 /* should never happen */
2197 DPRINTK("choking on default var... umm, no good.\n");
2198 goto err_dealloc_cmap;
2201 err = register_framebuffer(info);
2203 printk(KERN_ERR "cirrusfb: could not register "
2204 "fb device; err = %d!\n", err);
2205 goto err_dealloc_cmap;
2208 DPRINTK("EXIT, returning 0\n");
2212 fb_dealloc_cmap(&info->cmap);
2214 framebuffer_release(info);
2218 static void __devexit cirrusfb_cleanup(struct fb_info *info)
2220 struct cirrusfb_info *cinfo = info->par;
2223 switch_monitor(cinfo, 0);
2225 unregister_framebuffer(info);
2226 fb_dealloc_cmap(&info->cmap);
2227 printk("Framebuffer unregistered\n");
2229 framebuffer_release(info);
2235 static int cirrusfb_pci_register(struct pci_dev *pdev,
2236 const struct pci_device_id *ent)
2238 struct cirrusfb_info *cinfo;
2239 struct fb_info *info;
2240 enum cirrus_board btype;
2241 unsigned long board_addr, board_size;
2244 ret = pci_enable_device(pdev);
2246 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2250 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2252 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2258 cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
2260 DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
2261 pdev->resource[0].start, btype);
2262 DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);
2265 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2266 #ifdef CONFIG_PPC_PREP
2267 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2269 /* PReP dies if we ioremap the IO registers, but it works w/out... */
2270 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2272 DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");
2273 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2274 /* FIXME: this forces VGA. alternatives? */
2275 cinfo->regbase = NULL;
2278 DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",
2279 board_addr, info->fix.mmio_start);
2281 board_size = (btype == BT_GD5480) ?
2282 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);
2284 ret = pci_request_regions(pdev, "cirrusfb");
2286 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
2289 goto err_release_fb;
2291 #if 0 /* if the system didn't claim this region, we would... */
2292 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2293 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n"
2297 goto err_release_regions;
2300 if (request_region(0x3C0, 32, "cirrusfb"))
2301 release_io_ports = 1;
2303 info->screen_base = ioremap(board_addr, board_size);
2304 if (!info->screen_base) {
2306 goto err_release_legacy;
2309 info->fix.smem_start = board_addr;
2310 info->screen_size = board_size;
2311 cinfo->unmap = cirrusfb_pci_unmap;
2313 printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus "
2314 "Logic chipset on PCI bus\n",
2315 info->screen_size >> 10, board_addr);
2316 pci_set_drvdata(pdev, info);
2318 ret = cirrusfb_register(info);
2320 iounmap(info->screen_base);
2324 if (release_io_ports)
2325 release_region(0x3C0, 32);
2327 release_mem_region(0xA0000, 65535);
2328 err_release_regions:
2330 pci_release_regions(pdev);
2332 framebuffer_release(info);
2338 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2340 struct fb_info *info = pci_get_drvdata(pdev);
2343 cirrusfb_cleanup(info);
2348 static struct pci_driver cirrusfb_pci_driver = {
2350 .id_table = cirrusfb_pci_table,
2351 .probe = cirrusfb_pci_register,
2352 .remove = __devexit_p(cirrusfb_pci_unregister),
2355 .suspend = cirrusfb_pci_suspend,
2356 .resume = cirrusfb_pci_resume,
2360 #endif /* CONFIG_PCI */
2363 static int cirrusfb_zorro_register(struct zorro_dev *z,
2364 const struct zorro_device_id *ent)
2366 struct cirrusfb_info *cinfo;
2367 struct fb_info *info;
2368 enum cirrus_board btype;
2369 struct zorro_dev *z2 = NULL;
2370 unsigned long board_addr, board_size, size;
2373 btype = ent->driver_data;
2374 if (cirrusfb_zorro_table2[btype].id2)
2375 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2376 size = cirrusfb_zorro_table2[btype].size;
2377 printk(KERN_INFO "cirrusfb: %s board detected; ",
2378 cirrusfb_board_info[btype].name);
2380 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2382 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2388 cinfo->btype = btype;
2391 assert(btype != BT_NONE);
2393 board_addr = zorro_resource_start(z);
2394 board_size = zorro_resource_len(z);
2395 info->screen_size = size;
2397 if (!zorro_request_device(z, "cirrusfb")) {
2398 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
2402 goto err_release_fb;
2405 printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
2409 if (btype == BT_PICASSO4) {
2410 printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);
2412 /* To be precise, for the P4 this is not the */
2413 /* begin of the board, but the begin of RAM. */
2414 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2415 /* (note the ugly hardcoded 16M number) */
2416 cinfo->regbase = ioremap(board_addr, 16777216);
2417 if (!cinfo->regbase)
2418 goto err_release_region;
2420 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
2422 cinfo->regbase += 0x600000;
2423 info->fix.mmio_start = board_addr + 0x600000;
2425 info->fix.smem_start = board_addr + 16777216;
2426 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2427 if (!info->screen_base)
2428 goto err_unmap_regbase;
2430 printk(KERN_INFO " REG at $%lx\n",
2431 (unsigned long) z2->resource.start);
2433 info->fix.smem_start = board_addr;
2434 if (board_addr > 0x01000000)
2435 info->screen_base = ioremap(board_addr, board_size);
2437 info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2438 if (!info->screen_base)
2439 goto err_release_region;
2441 /* set address for REG area of board */
2442 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2443 info->fix.mmio_start = z2->resource.start;
2445 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
2448 cinfo->unmap = cirrusfb_zorro_unmap;
2450 printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
2451 zorro_set_drvdata(z, info);
2453 ret = cirrusfb_register(info);
2455 if (btype == BT_PICASSO4) {
2456 iounmap(info->screen_base);
2457 iounmap(cinfo->regbase - 0x600000);
2458 } else if (board_addr > 0x01000000)
2459 iounmap(info->screen_base);
2464 /* Parental advisory: explicit hack */
2465 iounmap(cinfo->regbase - 0x600000);
2467 release_region(board_addr, board_size);
2469 framebuffer_release(info);
2474 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2476 struct fb_info *info = zorro_get_drvdata(z);
2479 cirrusfb_cleanup(info);
2484 static struct zorro_driver cirrusfb_zorro_driver = {
2486 .id_table = cirrusfb_zorro_table,
2487 .probe = cirrusfb_zorro_register,
2488 .remove = __devexit_p(cirrusfb_zorro_unregister),
2490 #endif /* CONFIG_ZORRO */
2492 static int __init cirrusfb_init(void)
2497 char *option = NULL;
2499 if (fb_get_options("cirrusfb", &option))
2501 cirrusfb_setup(option);
2505 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2508 error |= pci_register_driver(&cirrusfb_pci_driver);
2514 static int __init cirrusfb_setup(char *options) {
2515 char *this_opt, s[32];
2520 if (!options || !*options)
2523 while ((this_opt = strsep(&options, ",")) != NULL) {
2527 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
2529 if (!strcmp(this_opt, "noaccel"))
2531 else if (!strncmp(this_opt, "mode:", 5))
2532 mode_option = this_opt + 5;
2534 mode_option = this_opt;
2544 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2545 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2546 MODULE_LICENSE("GPL");
2548 static void __exit cirrusfb_exit(void)
2551 pci_unregister_driver(&cirrusfb_pci_driver);
2554 zorro_unregister_driver(&cirrusfb_zorro_driver);
2558 module_init(cirrusfb_init);
2560 module_param(mode_option, charp, 0);
2561 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2564 module_exit(cirrusfb_exit);
2567 /**********************************************************************/
2568 /* about the following functions - I have used the same names for the */
2569 /* functions as Markus Wild did in his Retina driver for NetBSD as */
2570 /* they just made sense for this purpose. Apart from that, I wrote */
2571 /* these functions myself. */
2572 /**********************************************************************/
2574 /*** WGen() - write into one of the external/general registers ***/
2575 static void WGen(const struct cirrusfb_info *cinfo,
2576 int regnum, unsigned char val)
2578 unsigned long regofs = 0;
2580 if (cinfo->btype == BT_PICASSO) {
2581 /* Picasso II specific hack */
2582 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2583 regnum == CL_VSSM2) */
2584 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2588 vga_w(cinfo->regbase, regofs + regnum, val);
2591 /*** RGen() - read out one of the external/general registers ***/
2592 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2594 unsigned long regofs = 0;
2596 if (cinfo->btype == BT_PICASSO) {
2597 /* Picasso II specific hack */
2598 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2599 regnum == CL_VSSM2) */
2600 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2604 return vga_r(cinfo->regbase, regofs + regnum);
2607 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2608 static void AttrOn(const struct cirrusfb_info *cinfo)
2610 assert(cinfo != NULL);
2614 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2615 /* if we're just in "write value" mode, write back the */
2616 /* same value as before to not modify anything */
2617 vga_w(cinfo->regbase, VGA_ATT_IW,
2618 vga_r(cinfo->regbase, VGA_ATT_R));
2620 /* turn on video bit */
2621 /* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2622 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2624 /* dummy write on Reg0 to be on "write index" mode next time */
2625 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2630 /*** WHDR() - write into the Hidden DAC register ***/
2631 /* as the HDR is the only extension register that requires special treatment
2632 * (the other extension registers are accessible just like the "ordinary"
2633 * registers of their functional group) here is a specialized routine for
2636 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2638 unsigned char dummy;
2640 if (cinfo->btype == BT_PICASSO) {
2641 /* Klaus' hint for correct access to HDR on some boards */
2642 /* first write 0 to pixel mask (3c6) */
2643 WGen(cinfo, VGA_PEL_MSK, 0x00);
2645 /* next read dummy from pixel address (3c8) */
2646 dummy = RGen(cinfo, VGA_PEL_IW);
2649 /* now do the usual stuff to access the HDR */
2651 dummy = RGen(cinfo, VGA_PEL_MSK);
2653 dummy = RGen(cinfo, VGA_PEL_MSK);
2655 dummy = RGen(cinfo, VGA_PEL_MSK);
2657 dummy = RGen(cinfo, VGA_PEL_MSK);
2660 WGen(cinfo, VGA_PEL_MSK, val);
2663 if (cinfo->btype == BT_PICASSO) {
2664 /* now first reset HDR access counter */
2665 dummy = RGen(cinfo, VGA_PEL_IW);
2668 /* and at the end, restore the mask value */
2669 /* ## is this mask always 0xff? */
2670 WGen(cinfo, VGA_PEL_MSK, 0xff);
2675 /*** WSFR() - write to the "special function register" (SFR) ***/
2676 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2679 assert(cinfo->regbase != NULL);
2681 z_writeb(val, cinfo->regbase + 0x8000);
2685 /* The Picasso has a second register for switching the monitor bit */
2686 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2689 /* writing an arbitrary value to this one causes the monitor switcher */
2690 /* to flip to Amiga display */
2691 assert(cinfo->regbase != NULL);
2693 z_writeb(val, cinfo->regbase + 0x9000);
2697 /*** WClut - set CLUT entry (range: 0..63) ***/
2698 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2699 unsigned char green, unsigned char blue)
2701 unsigned int data = VGA_PEL_D;
2703 /* address write mode register is not translated.. */
2704 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2706 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2707 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2708 /* but DAC data register IS, at least for Picasso II */
2709 if (cinfo->btype == BT_PICASSO)
2711 vga_w(cinfo->regbase, data, red);
2712 vga_w(cinfo->regbase, data, green);
2713 vga_w(cinfo->regbase, data, blue);
2715 vga_w(cinfo->regbase, data, blue);
2716 vga_w(cinfo->regbase, data, green);
2717 vga_w(cinfo->regbase, data, red);
2722 /*** RClut - read CLUT entry (range 0..63) ***/
2723 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2724 unsigned char *green, unsigned char *blue)
2726 unsigned int data = VGA_PEL_D;
2728 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2730 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2731 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2732 if (cinfo->btype == BT_PICASSO)
2734 *red = vga_r(cinfo->regbase, data);
2735 *green = vga_r(cinfo->regbase, data);
2736 *blue = vga_r(cinfo->regbase, data);
2738 *blue = vga_r(cinfo->regbase, data);
2739 *green = vga_r(cinfo->regbase, data);
2740 *red = vga_r(cinfo->regbase, data);
2745 /*******************************************************************
2748 Wait for the BitBLT engine to complete a possible earlier job
2749 *********************************************************************/
2751 /* FIXME: use interrupts instead */
2752 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2754 /* now busy-wait until we're done */
2755 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2759 /*******************************************************************
2762 perform accelerated "scrolling"
2763 ********************************************************************/
2765 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2766 u_short curx, u_short cury,
2767 u_short destx, u_short desty,
2768 u_short width, u_short height,
2769 u_short line_length)
2771 u_short nwidth, nheight;
2778 nheight = height - 1;
2781 /* if source adr < dest addr, do the Blt backwards */
2782 if (cury <= desty) {
2783 if (cury == desty) {
2784 /* if src and dest are on the same line, check x */
2791 /* standard case: forward blitting */
2792 nsrc = (cury * line_length) + curx;
2793 ndest = (desty * line_length) + destx;
2795 /* this means start addresses are at the end,
2796 * counting backwards
2798 nsrc = cury * line_length + curx +
2799 nheight * line_length + nwidth;
2800 ndest = desty * line_length + destx +
2801 nheight * line_length + nwidth;
2805 run-down of registers to be programmed:
2813 VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
2817 cirrusfb_WaitBLT(regbase);
2819 /* pitch: set to line_length */
2820 /* dest pitch low */
2821 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2823 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2824 /* source pitch low */
2825 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2826 /* source pitch hi */
2827 vga_wgfx(regbase, CL_GR27, line_length >> 8);
2829 /* BLT width: actual number of pixels - 1 */
2831 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2833 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2835 /* BLT height: actual number of lines -1 */
2836 /* BLT height low */
2837 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2839 vga_wgfx(regbase, CL_GR23, nheight >> 8);
2841 /* BLT destination */
2843 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2845 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2847 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2851 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2853 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2855 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2858 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
2860 /* BLT ROP: SrcCopy */
2861 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2863 /* and finally: GO! */
2864 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2869 /*******************************************************************
2872 perform accelerated rectangle fill
2873 ********************************************************************/
2875 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2876 u_short x, u_short y, u_short width, u_short height,
2877 u_char color, u_short line_length)
2879 u_short nwidth, nheight;
2886 nheight = height - 1;
2888 ndest = (y * line_length) + x;
2890 cirrusfb_WaitBLT(regbase);
2892 /* pitch: set to line_length */
2893 vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
2894 vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */
2895 vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2896 vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */
2898 /* BLT width: actual number of pixels - 1 */
2899 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
2900 vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */
2902 /* BLT height: actual number of lines -1 */
2903 vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */
2904 vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */
2906 /* BLT destination */
2908 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2910 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2912 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2914 /* BLT source: set to 0 (is a dummy here anyway) */
2915 vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */
2916 vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */
2917 vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */
2919 /* This is a ColorExpand Blt, using the */
2920 /* same color for foreground and background */
2921 vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */
2922 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */
2925 if (bits_per_pixel == 16) {
2926 vga_wgfx(regbase, CL_GR10, color); /* foreground color */
2927 vga_wgfx(regbase, CL_GR11, color); /* background color */
2930 } else if (bits_per_pixel == 32) {
2931 vga_wgfx(regbase, CL_GR10, color); /* foreground color */
2932 vga_wgfx(regbase, CL_GR11, color); /* background color */
2933 vga_wgfx(regbase, CL_GR12, color); /* foreground color */
2934 vga_wgfx(regbase, CL_GR13, color); /* background color */
2935 vga_wgfx(regbase, CL_GR14, 0); /* foreground color */
2936 vga_wgfx(regbase, CL_GR15, 0); /* background color */
2940 /* BLT mode: color expand, Enable 8x8 copy (faster?) */
2941 vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
2943 /* BLT ROP: SrcCopy */
2944 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2946 /* and finally: GO! */
2947 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2952 /**************************************************************************
2953 * bestclock() - determine closest possible clock lower(?) than the
2954 * desired pixel clock
2955 **************************************************************************/
2956 static void bestclock(long freq, long *best, long *nom,
2957 long *den, long *div, long maxfreq)
2961 assert(best != NULL);
2962 assert(nom != NULL);
2963 assert(den != NULL);
2964 assert(div != NULL);
2965 assert(maxfreq > 0);
2982 for (n = 32; n < 128; n++) {
2985 d = (143181 * n) / f;
2986 if ((d >= 7) && (d <= 63)) {
2993 h = ((14318 * n) / temp) >> s;
2994 if (abs(h - freq) < abs(*best - freq)) {
3002 if ((d >= 7) && (d <= 63)) {
3007 h = ((14318 * n) / d) >> s;
3008 if (abs(h - freq) < abs(*best - freq)) {
3017 DPRINTK("Best possible values for given frequency:\n");
3018 DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n",
3019 freq, *nom, *den, *div);
3024 /* -------------------------------------------------------------------------
3026 * debugging functions
3028 * -------------------------------------------------------------------------
3031 #ifdef CIRRUSFB_DEBUG
3034 * cirrusfb_dbg_print_byte
3035 * @name: name associated with byte value to be displayed
3036 * @val: byte value to be displayed
3039 * Display an indented string, along with a hexidecimal byte value, and
3040 * its decoded bits. Bits 7 through 0 are listed in left-to-right
3045 void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
3047 DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
3049 val & 0x80 ? '1' : '0',
3050 val & 0x40 ? '1' : '0',
3051 val & 0x20 ? '1' : '0',
3052 val & 0x10 ? '1' : '0',
3053 val & 0x08 ? '1' : '0',
3054 val & 0x04 ? '1' : '0',
3055 val & 0x02 ? '1' : '0',
3056 val & 0x01 ? '1' : '0');
3060 * cirrusfb_dbg_print_regs
3061 * @base: If using newmmio, the newmmio base address, otherwise %NULL
3062 * @reg_class: type of registers to read: %CRT, or %SEQ
3065 * Dumps the given list of VGA CRTC registers. If @base is %NULL,
3066 * old-style I/O ports are queried for information, otherwise MMIO is
3067 * used at the given @base address to query the information.
3071 void cirrusfb_dbg_print_regs(caddr_t regbase,
3072 enum cirrusfb_dbg_reg_class reg_class, ...)
3075 unsigned char val = 0;
3079 va_start(list, reg_class);
3081 name = va_arg(list, char *);
3082 while (name != NULL) {
3083 reg = va_arg(list, int);
3085 switch (reg_class) {
3087 val = vga_rcrt(regbase, (unsigned char) reg);
3090 val = vga_rseq(regbase, (unsigned char) reg);
3093 /* should never occur */
3098 cirrusfb_dbg_print_byte(name, val);
3100 name = va_arg(list, char *);
3113 static void cirrusfb_dump(void)
3115 cirrusfb_dbg_reg_dump(NULL);
3119 * cirrusfb_dbg_reg_dump
3120 * @base: If using newmmio, the newmmio base address, otherwise %NULL
3123 * Dumps a list of interesting VGA and CIRRUSFB registers. If @base is %NULL,
3124 * old-style I/O ports are queried for information, otherwise MMIO is
3125 * used at the given @base address to query the information.
3129 void cirrusfb_dbg_reg_dump(caddr_t regbase)
3131 DPRINTK("CIRRUSFB VGA CRTC register dump:\n");
3133 cirrusfb_dbg_print_regs(regbase, CRT,
3185 DPRINTK("CIRRUSFB VGA SEQ register dump:\n");
3187 cirrusfb_dbg_print_regs(regbase, SEQ,
3219 #endif /* CIRRUSFB_DEBUG */