cirrusfb: GD5446 fixes
[linux-2.6/mini2440.git] / drivers / video / cirrusfb.c
blob6603273f4ce59a886374609c5288369866b85127
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,
99 BT_PICCOLO,
100 BT_PICASSO,
101 BT_SPECTRUM,
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_8bpp = 0xF1,
149 .sr1f = 0x20
151 [BT_PICCOLO] = {
152 .name = "CL Piccolo",
153 .maxclock = {
154 /* guess */
155 90000, 90000, 90000, 90000, 90000
157 .init_sr07 = true,
158 .init_sr1f = true,
159 .scrn_start_bit19 = false,
160 .sr07 = 0x80,
161 .sr07_1bpp = 0x80,
162 .sr07_8bpp = 0x81,
163 .sr1f = 0x22
165 [BT_PICASSO] = {
166 .name = "CL Picasso",
167 .maxclock = {
168 /* guess */
169 90000, 90000, 90000, 90000, 90000
171 .init_sr07 = true,
172 .init_sr1f = true,
173 .scrn_start_bit19 = false,
174 .sr07 = 0x20,
175 .sr07_1bpp = 0x20,
176 .sr07_8bpp = 0x21,
177 .sr1f = 0x22
179 [BT_SPECTRUM] = {
180 .name = "CL Spectrum",
181 .maxclock = {
182 /* guess */
183 90000, 90000, 90000, 90000, 90000
185 .init_sr07 = true,
186 .init_sr1f = true,
187 .scrn_start_bit19 = false,
188 .sr07 = 0x80,
189 .sr07_1bpp = 0x80,
190 .sr07_8bpp = 0x81,
191 .sr1f = 0x22
193 [BT_PICASSO4] = {
194 .name = "CL Picasso4",
195 .maxclock = {
196 135100, 135100, 85500, 85500, 0
198 .init_sr07 = true,
199 .init_sr1f = false,
200 .scrn_start_bit19 = true,
201 .sr07 = 0xA0,
202 .sr07_1bpp = 0xA0,
203 .sr07_1bpp_mux = 0xA6,
204 .sr07_8bpp = 0xA1,
205 .sr07_8bpp_mux = 0xA7,
206 .sr1f = 0
208 [BT_ALPINE] = {
209 .name = "CL Alpine",
210 .maxclock = {
211 /* for the GD5430. GD5446 can do more... */
212 85500, 85500, 50000, 28500, 0
214 .init_sr07 = true,
215 .init_sr1f = true,
216 .scrn_start_bit19 = true,
217 .sr07 = 0xA0,
218 .sr07_1bpp = 0xA0,
219 .sr07_1bpp_mux = 0xA6,
220 .sr07_8bpp = 0xA1,
221 .sr07_8bpp_mux = 0xA7,
222 .sr1f = 0x1C
224 [BT_GD5480] = {
225 .name = "CL GD5480",
226 .maxclock = {
227 135100, 200000, 200000, 135100, 135100
229 .init_sr07 = true,
230 .init_sr1f = true,
231 .scrn_start_bit19 = true,
232 .sr07 = 0x10,
233 .sr07_1bpp = 0x11,
234 .sr07_8bpp = 0x11,
235 .sr1f = 0x1C
237 [BT_LAGUNA] = {
238 .name = "CL Laguna",
239 .maxclock = {
240 /* taken from X11 code */
241 170000, 170000, 170000, 170000, 135100,
243 .init_sr07 = false,
244 .init_sr1f = false,
245 .scrn_start_bit19 = true,
247 [BT_LAGUNAB] = {
248 .name = "CL Laguna AGP",
249 .maxclock = {
250 /* taken from X11 code */
251 170000, 250000, 170000, 170000, 135100,
253 .init_sr07 = false,
254 .init_sr1f = false,
255 .scrn_start_bit19 = true,
259 #ifdef CONFIG_PCI
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_LAGUNAB), /* CL Laguna 3DA*/
275 { 0, }
277 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
278 #undef CHIP
279 #endif /* CONFIG_PCI */
281 #ifdef CONFIG_ZORRO
282 static const struct zorro_device_id cirrusfb_zorro_table[] = {
284 .id = ZORRO_PROD_HELFRICH_SD64_RAM,
285 .driver_data = BT_SD64,
286 }, {
287 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
288 .driver_data = BT_PICCOLO,
289 }, {
290 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
291 .driver_data = BT_PICASSO,
292 }, {
293 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
294 .driver_data = BT_SPECTRUM,
295 }, {
296 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
297 .driver_data = BT_PICASSO4,
299 { 0 }
302 static const struct {
303 zorro_id id2;
304 unsigned long size;
305 } cirrusfb_zorro_table2[] = {
306 [BT_SD64] = {
307 .id2 = ZORRO_PROD_HELFRICH_SD64_REG,
308 .size = 0x400000
310 [BT_PICCOLO] = {
311 .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG,
312 .size = 0x200000
314 [BT_PICASSO] = {
315 .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
316 .size = 0x200000
318 [BT_SPECTRUM] = {
319 .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
320 .size = 0x200000
322 [BT_PICASSO4] = {
323 .id2 = 0,
324 .size = 0x400000
327 #endif /* CONFIG_ZORRO */
329 #ifdef CIRRUSFB_DEBUG
330 enum cirrusfb_dbg_reg_class {
331 CRT,
334 #endif /* CIRRUSFB_DEBUG */
336 /* info about board */
337 struct cirrusfb_info {
338 u8 __iomem *regbase;
339 u8 __iomem *laguna_mmio;
340 enum cirrus_board btype;
341 unsigned char SFR; /* Shadow of special function register */
343 int multiplexing;
344 int blank_mode;
345 u32 pseudo_palette[16];
347 void (*unmap)(struct fb_info *info);
350 static int noaccel __devinitdata;
351 static char *mode_option __devinitdata = "640x480@60";
353 /****************************************************************************/
354 /**** BEGIN PROTOTYPES ******************************************************/
356 /*--- Interface used by the world ------------------------------------------*/
357 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
358 struct fb_info *info);
360 /*--- Internal routines ----------------------------------------------------*/
361 static void init_vgachip(struct fb_info *info);
362 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
363 static void WGen(const struct cirrusfb_info *cinfo,
364 int regnum, unsigned char val);
365 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
366 static void AttrOn(const struct cirrusfb_info *cinfo);
367 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
368 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
369 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
370 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
371 unsigned char red, unsigned char green, unsigned char blue);
372 #if 0
373 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
374 unsigned char *red, unsigned char *green,
375 unsigned char *blue);
376 #endif
377 static void cirrusfb_WaitBLT(u8 __iomem *regbase);
378 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
379 u_short curx, u_short cury,
380 u_short destx, u_short desty,
381 u_short width, u_short height,
382 u_short line_length);
383 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
384 u_short x, u_short y,
385 u_short width, u_short height,
386 u32 fg_color, u32 bg_color,
387 u_short line_length, u_char blitmode);
389 static void bestclock(long freq, int *nom, int *den, int *div);
391 #ifdef CIRRUSFB_DEBUG
392 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
393 static void cirrusfb_dbg_print_regs(struct fb_info *info,
394 caddr_t regbase,
395 enum cirrusfb_dbg_reg_class reg_class, ...);
396 #endif /* CIRRUSFB_DEBUG */
398 /*** END PROTOTYPES ********************************************************/
399 /*****************************************************************************/
400 /*** BEGIN Interface Used by the World ***************************************/
402 static inline int is_laguna(const struct cirrusfb_info *cinfo)
404 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
407 static int opencount;
409 /*--- Open /dev/fbx ---------------------------------------------------------*/
410 static int cirrusfb_open(struct fb_info *info, int user)
412 if (opencount++ == 0)
413 switch_monitor(info->par, 1);
414 return 0;
417 /*--- Close /dev/fbx --------------------------------------------------------*/
418 static int cirrusfb_release(struct fb_info *info, int user)
420 if (--opencount == 0)
421 switch_monitor(info->par, 0);
422 return 0;
425 /**** END Interface used by the World *************************************/
426 /****************************************************************************/
427 /**** BEGIN Hardware specific Routines **************************************/
429 /* Check if the MCLK is not a better clock source */
430 static int cirrusfb_check_mclk(struct fb_info *info, long freq)
432 struct cirrusfb_info *cinfo = info->par;
433 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
435 /* Read MCLK value */
436 mclk = (14318 * mclk) >> 3;
437 dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
439 /* Determine if we should use MCLK instead of VCLK, and if so, what we
440 * should divide it by to get VCLK
443 if (abs(freq - mclk) < 250) {
444 dev_dbg(info->device, "Using VCLK = MCLK\n");
445 return 1;
446 } else if (abs(freq - (mclk / 2)) < 250) {
447 dev_dbg(info->device, "Using VCLK = MCLK/2\n");
448 return 2;
451 return 0;
454 static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
455 struct fb_info *info)
457 long freq;
458 long maxclock;
459 struct cirrusfb_info *cinfo = info->par;
460 unsigned maxclockidx = var->bits_per_pixel >> 3;
462 /* convert from ps to kHz */
463 freq = PICOS2KHZ(var->pixclock);
465 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
467 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
468 cinfo->multiplexing = 0;
470 /* If the frequency is greater than we can support, we might be able
471 * to use multiplexing for the video mode */
472 if (freq > maxclock) {
473 switch (cinfo->btype) {
474 case BT_ALPINE:
475 case BT_GD5480:
476 cinfo->multiplexing = 1;
477 break;
479 default:
480 dev_err(info->device,
481 "Frequency greater than maxclock (%ld kHz)\n",
482 maxclock);
483 return -EINVAL;
486 #if 0
487 /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
488 * the VCLK is double the pixel clock. */
489 switch (var->bits_per_pixel) {
490 case 16:
491 case 32:
492 if (var->xres <= 800)
493 /* Xbh has this type of clock for 32-bit */
494 freq /= 2;
495 break;
497 #endif
498 return 0;
501 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
502 struct fb_info *info)
504 int yres;
505 /* memory size in pixels */
506 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
508 switch (var->bits_per_pixel) {
509 case 1:
510 var->red.offset = 0;
511 var->red.length = 1;
512 var->green = var->red;
513 var->blue = var->red;
514 break;
516 case 8:
517 var->red.offset = 0;
518 var->red.length = 8;
519 var->green = var->red;
520 var->blue = var->red;
521 break;
523 case 16:
524 if (isPReP) {
525 var->red.offset = 2;
526 var->green.offset = -3;
527 var->blue.offset = 8;
528 } else {
529 var->red.offset = 11;
530 var->green.offset = 5;
531 var->blue.offset = 0;
533 var->red.length = 5;
534 var->green.length = 6;
535 var->blue.length = 5;
536 break;
538 case 32:
539 if (isPReP) {
540 var->red.offset = 8;
541 var->green.offset = 16;
542 var->blue.offset = 24;
543 } else {
544 var->red.offset = 16;
545 var->green.offset = 8;
546 var->blue.offset = 0;
548 var->red.length = 8;
549 var->green.length = 8;
550 var->blue.length = 8;
551 break;
553 default:
554 dev_dbg(info->device,
555 "Unsupported bpp size: %d\n", var->bits_per_pixel);
556 assert(false);
557 /* should never occur */
558 break;
561 if (var->xres_virtual < var->xres)
562 var->xres_virtual = var->xres;
563 /* use highest possible virtual resolution */
564 if (var->yres_virtual == -1) {
565 var->yres_virtual = pixels / var->xres_virtual;
567 dev_info(info->device,
568 "virtual resolution set to maximum of %dx%d\n",
569 var->xres_virtual, var->yres_virtual);
571 if (var->yres_virtual < var->yres)
572 var->yres_virtual = var->yres;
574 if (var->xres_virtual * var->yres_virtual > pixels) {
575 dev_err(info->device, "mode %dx%dx%d rejected... "
576 "virtual resolution too high to fit into video memory!\n",
577 var->xres_virtual, var->yres_virtual,
578 var->bits_per_pixel);
579 return -EINVAL;
582 if (var->xoffset < 0)
583 var->xoffset = 0;
584 if (var->yoffset < 0)
585 var->yoffset = 0;
587 /* truncate xoffset and yoffset to maximum if too high */
588 if (var->xoffset > var->xres_virtual - var->xres)
589 var->xoffset = var->xres_virtual - var->xres - 1;
590 if (var->yoffset > var->yres_virtual - var->yres)
591 var->yoffset = var->yres_virtual - var->yres - 1;
593 var->red.msb_right =
594 var->green.msb_right =
595 var->blue.msb_right =
596 var->transp.offset =
597 var->transp.length =
598 var->transp.msb_right = 0;
600 yres = var->yres;
601 if (var->vmode & FB_VMODE_DOUBLE)
602 yres *= 2;
603 else if (var->vmode & FB_VMODE_INTERLACED)
604 yres = (yres + 1) / 2;
606 if (yres >= 1280) {
607 dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
608 "special treatment required! (TODO)\n");
609 return -EINVAL;
612 if (cirrusfb_check_pixclock(var, info))
613 return -EINVAL;
615 return 0;
618 static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
620 struct cirrusfb_info *cinfo = info->par;
621 unsigned char old1f, old1e;
623 assert(cinfo != NULL);
624 old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
626 if (div) {
627 dev_dbg(info->device, "Set %s as pixclock source.\n",
628 (div == 2) ? "MCLK/2" : "MCLK");
629 old1f |= 0x40;
630 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
631 if (div == 2)
632 old1e |= 1;
634 vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
636 vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
639 /*************************************************************************
640 cirrusfb_set_par_foo()
642 actually writes the values for a new video mode into the hardware,
643 **************************************************************************/
644 static int cirrusfb_set_par_foo(struct fb_info *info)
646 struct cirrusfb_info *cinfo = info->par;
647 struct fb_var_screeninfo *var = &info->var;
648 u8 __iomem *regbase = cinfo->regbase;
649 unsigned char tmp;
650 int pitch;
651 const struct cirrusfb_board_info_rec *bi;
652 int hdispend, hsyncstart, hsyncend, htotal;
653 int yres, vdispend, vsyncstart, vsyncend, vtotal;
654 long freq;
655 int nom, den, div;
656 unsigned int control = 0, format = 0, threshold = 0;
658 dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
659 var->xres, var->yres, var->bits_per_pixel);
661 switch (var->bits_per_pixel) {
662 case 1:
663 info->fix.line_length = var->xres_virtual / 8;
664 info->fix.visual = FB_VISUAL_MONO10;
665 break;
667 case 8:
668 info->fix.line_length = var->xres_virtual;
669 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
670 break;
672 case 16:
673 case 32:
674 info->fix.line_length = var->xres_virtual *
675 var->bits_per_pixel >> 3;
676 info->fix.visual = FB_VISUAL_TRUECOLOR;
677 break;
679 info->fix.type = FB_TYPE_PACKED_PIXELS;
681 init_vgachip(info);
683 bi = &cirrusfb_board_info[cinfo->btype];
685 hsyncstart = var->xres + var->right_margin;
686 hsyncend = hsyncstart + var->hsync_len;
687 htotal = (hsyncend + var->left_margin) / 8 - 5;
688 hdispend = var->xres / 8 - 1;
689 hsyncstart = hsyncstart / 8 + 1;
690 hsyncend = hsyncend / 8 + 1;
692 yres = var->yres;
693 vsyncstart = yres + var->lower_margin;
694 vsyncend = vsyncstart + var->vsync_len;
695 vtotal = vsyncend + var->upper_margin;
696 vdispend = yres - 1;
698 if (var->vmode & FB_VMODE_DOUBLE) {
699 yres *= 2;
700 vsyncstart *= 2;
701 vsyncend *= 2;
702 vtotal *= 2;
703 } else if (var->vmode & FB_VMODE_INTERLACED) {
704 yres = (yres + 1) / 2;
705 vsyncstart = (vsyncstart + 1) / 2;
706 vsyncend = (vsyncend + 1) / 2;
707 vtotal = (vtotal + 1) / 2;
710 vtotal -= 2;
711 vsyncstart -= 1;
712 vsyncend -= 1;
714 if (yres >= 1024) {
715 vtotal /= 2;
716 vsyncstart /= 2;
717 vsyncend /= 2;
718 vdispend /= 2;
720 if (cinfo->multiplexing) {
721 htotal /= 2;
722 hsyncstart /= 2;
723 hsyncend /= 2;
724 hdispend /= 2;
726 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
727 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
729 /* if debugging is enabled, all parameters get output before writing */
730 dev_dbg(info->device, "CRT0: %d\n", htotal);
731 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
733 dev_dbg(info->device, "CRT1: %d\n", hdispend);
734 vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
736 dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
737 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
739 /* + 128: Compatible read */
740 dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
741 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
742 128 + ((htotal + 5) % 32));
744 dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
745 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
747 tmp = hsyncend % 32;
748 if ((htotal + 5) & 32)
749 tmp += 128;
750 dev_dbg(info->device, "CRT5: %d\n", tmp);
751 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
753 dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
754 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
756 tmp = 16; /* LineCompare bit #9 */
757 if (vtotal & 256)
758 tmp |= 1;
759 if (vdispend & 256)
760 tmp |= 2;
761 if (vsyncstart & 256)
762 tmp |= 4;
763 if ((vdispend + 1) & 256)
764 tmp |= 8;
765 if (vtotal & 512)
766 tmp |= 32;
767 if (vdispend & 512)
768 tmp |= 64;
769 if (vsyncstart & 512)
770 tmp |= 128;
771 dev_dbg(info->device, "CRT7: %d\n", tmp);
772 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
774 tmp = 0x40; /* LineCompare bit #8 */
775 if ((vdispend + 1) & 512)
776 tmp |= 0x20;
777 if (var->vmode & FB_VMODE_DOUBLE)
778 tmp |= 0x80;
779 dev_dbg(info->device, "CRT9: %d\n", tmp);
780 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
782 dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
783 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
785 dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
786 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
788 dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
789 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
791 dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
792 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
794 dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
795 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
797 dev_dbg(info->device, "CRT18: 0xff\n");
798 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
800 tmp = 0;
801 if (var->vmode & FB_VMODE_INTERLACED)
802 tmp |= 1;
803 if ((htotal + 5) & 64)
804 tmp |= 16;
805 if ((htotal + 5) & 128)
806 tmp |= 32;
807 if (vtotal & 256)
808 tmp |= 64;
809 if (vtotal & 512)
810 tmp |= 128;
812 dev_dbg(info->device, "CRT1a: %d\n", tmp);
813 vga_wcrt(regbase, CL_CRT1A, tmp);
815 freq = PICOS2KHZ(var->pixclock);
816 bestclock(freq, &nom, &den, &div);
818 dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n",
819 freq, nom, den, div);
821 /* set VCLK0 */
822 /* hardware RefClock: 14.31818 MHz */
823 /* formula: VClk = (OSC * N) / (D * (1+P)) */
824 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
826 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4) {
827 /* if freq is close to mclk or mclk/2 select mclk
828 * as clock source
830 int divMCLK = cirrusfb_check_mclk(info, freq);
831 if (divMCLK) {
832 nom = 0;
833 cirrusfb_set_mclk_as_source(info, divMCLK);
836 if (is_laguna(cinfo)) {
837 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
838 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
839 unsigned short tile_control;
841 if (cinfo->btype == BT_LAGUNAB) {
842 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
843 tile_control &= ~0x80;
844 fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
847 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
848 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
849 control = fb_readw(cinfo->laguna_mmio + 0x402);
850 threshold = fb_readw(cinfo->laguna_mmio + 0xea);
851 control &= ~0x6800;
852 format = 0;
853 threshold &= 0xffe0 & 0x3fbf;
855 if (nom) {
856 tmp = den << 1;
857 if (div != 0)
858 tmp |= 1;
859 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
860 if ((cinfo->btype == BT_SD64) ||
861 (cinfo->btype == BT_ALPINE) ||
862 (cinfo->btype == BT_GD5480))
863 tmp |= 0x80;
865 dev_dbg(info->device, "CL_SEQR1B: %d\n", (int) tmp);
866 /* Laguna chipset has reversed clock registers */
867 if (is_laguna(cinfo)) {
868 vga_wseq(regbase, CL_SEQRE, tmp);
869 vga_wseq(regbase, CL_SEQR1E, nom);
870 } else {
871 vga_wseq(regbase, CL_SEQRB, nom);
872 vga_wseq(regbase, CL_SEQR1B, tmp);
876 if (yres >= 1024)
877 /* 1280x1024 */
878 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
879 else
880 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
881 * address wrap, no compat. */
882 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
884 /* don't know if it would hurt to also program this if no interlaced */
885 /* mode is used, but I feel better this way.. :-) */
886 if (var->vmode & FB_VMODE_INTERLACED)
887 vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
888 else
889 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
891 /* adjust horizontal/vertical sync type (low/high) */
892 /* enable display memory & CRTC I/O address for color mode */
893 tmp = 0x03;
894 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
895 tmp |= 0x40;
896 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
897 tmp |= 0x80;
898 if (is_laguna(cinfo))
899 tmp |= 0xc;
900 WGen(cinfo, VGA_MIS_W, tmp);
902 /* text cursor on and start line */
903 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
904 /* text cursor end line */
905 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
907 /******************************************************
909 * 1 bpp
913 /* programming for different color depths */
914 if (var->bits_per_pixel == 1) {
915 dev_dbg(info->device, "preparing for 1 bit deep display\n");
916 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
918 /* SR07 */
919 switch (cinfo->btype) {
920 case BT_SD64:
921 case BT_PICCOLO:
922 case BT_PICASSO:
923 case BT_SPECTRUM:
924 case BT_PICASSO4:
925 case BT_ALPINE:
926 case BT_GD5480:
927 vga_wseq(regbase, CL_SEQR7,
928 cinfo->multiplexing ?
929 bi->sr07_1bpp_mux : bi->sr07_1bpp);
930 break;
932 case BT_LAGUNA:
933 case BT_LAGUNAB:
934 vga_wseq(regbase, CL_SEQR7,
935 vga_rseq(regbase, CL_SEQR7) & ~0x01);
936 break;
938 default:
939 dev_warn(info->device, "unknown Board\n");
940 break;
943 /* Extended Sequencer Mode */
944 switch (cinfo->btype) {
945 case BT_SD64:
946 /* setting the SEQRF on SD64 is not necessary
947 * (only during init)
949 /* MCLK select */
950 vga_wseq(regbase, CL_SEQR1F, 0x1a);
951 break;
953 case BT_PICCOLO:
954 case BT_SPECTRUM:
955 /* ### ueberall 0x22? */
956 /* ##vorher 1c MCLK select */
957 vga_wseq(regbase, CL_SEQR1F, 0x22);
958 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
959 vga_wseq(regbase, CL_SEQRF, 0xb0);
960 break;
962 case BT_PICASSO:
963 /* ##vorher 22 MCLK select */
964 vga_wseq(regbase, CL_SEQR1F, 0x22);
965 /* ## vorher d0 avoid FIFO underruns..? */
966 vga_wseq(regbase, CL_SEQRF, 0xd0);
967 break;
969 case BT_PICASSO4:
970 case BT_ALPINE:
971 case BT_GD5480:
972 case BT_LAGUNA:
973 case BT_LAGUNAB:
974 /* do nothing */
975 break;
977 default:
978 dev_warn(info->device, "unknown Board\n");
979 break;
982 /* pixel mask: pass-through for first plane */
983 WGen(cinfo, VGA_PEL_MSK, 0x01);
984 if (cinfo->multiplexing)
985 /* hidden dac reg: 1280x1024 */
986 WHDR(cinfo, 0x4a);
987 else
988 /* hidden dac: nothing */
989 WHDR(cinfo, 0);
990 /* memory mode: odd/even, ext. memory */
991 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
992 /* plane mask: only write to first plane */
993 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
996 /******************************************************
998 * 8 bpp
1002 else if (var->bits_per_pixel == 8) {
1003 dev_dbg(info->device, "preparing for 8 bit deep display\n");
1004 switch (cinfo->btype) {
1005 case BT_SD64:
1006 case BT_PICCOLO:
1007 case BT_PICASSO:
1008 case BT_SPECTRUM:
1009 case BT_PICASSO4:
1010 case BT_ALPINE:
1011 case BT_GD5480:
1012 vga_wseq(regbase, CL_SEQR7,
1013 cinfo->multiplexing ?
1014 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1015 break;
1017 case BT_LAGUNA:
1018 case BT_LAGUNAB:
1019 vga_wseq(regbase, CL_SEQR7,
1020 vga_rseq(regbase, CL_SEQR7) | 0x01);
1021 threshold |= 0x10;
1022 break;
1024 default:
1025 dev_warn(info->device, "unknown Board\n");
1026 break;
1029 switch (cinfo->btype) {
1030 case BT_SD64:
1031 /* MCLK select */
1032 vga_wseq(regbase, CL_SEQR1F, 0x1d);
1033 break;
1035 case BT_PICCOLO:
1036 case BT_PICASSO:
1037 case BT_SPECTRUM:
1038 /* ### vorher 1c MCLK select */
1039 vga_wseq(regbase, CL_SEQR1F, 0x22);
1040 /* Fast Page-Mode writes */
1041 vga_wseq(regbase, CL_SEQRF, 0xb0);
1042 break;
1044 case BT_PICASSO4:
1045 #ifdef CONFIG_ZORRO
1046 /* ### INCOMPLETE!! */
1047 vga_wseq(regbase, CL_SEQRF, 0xb8);
1048 #endif
1049 case BT_ALPINE:
1050 /* We already set SRF and SR1F */
1051 break;
1053 case BT_GD5480:
1054 case BT_LAGUNA:
1055 case BT_LAGUNAB:
1056 /* do nothing */
1057 break;
1059 default:
1060 dev_warn(info->device, "unknown board\n");
1061 break;
1064 /* mode register: 256 color mode */
1065 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1066 if (cinfo->multiplexing)
1067 /* hidden dac reg: 1280x1024 */
1068 WHDR(cinfo, 0x4a);
1069 else
1070 /* hidden dac: nothing */
1071 WHDR(cinfo, 0);
1074 /******************************************************
1076 * 16 bpp
1080 else if (var->bits_per_pixel == 16) {
1081 dev_dbg(info->device, "preparing for 16 bit deep display\n");
1082 switch (cinfo->btype) {
1083 case BT_SD64:
1084 /* Extended Sequencer Mode: 256c col. mode */
1085 vga_wseq(regbase, CL_SEQR7, 0xf7);
1086 /* MCLK select */
1087 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1088 break;
1090 case BT_PICCOLO:
1091 case BT_SPECTRUM:
1092 vga_wseq(regbase, CL_SEQR7, 0x87);
1093 /* Fast Page-Mode writes */
1094 vga_wseq(regbase, CL_SEQRF, 0xb0);
1095 /* MCLK select */
1096 vga_wseq(regbase, CL_SEQR1F, 0x22);
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 /* MCLK select */
1104 vga_wseq(regbase, CL_SEQR1F, 0x22);
1105 break;
1107 case BT_PICASSO4:
1108 case BT_ALPINE:
1109 vga_wseq(regbase, CL_SEQR7, 0xa7);
1110 break;
1112 case BT_GD5480:
1113 vga_wseq(regbase, CL_SEQR7, 0x17);
1114 /* We already set SRF and SR1F */
1115 break;
1117 case BT_LAGUNA:
1118 case BT_LAGUNAB:
1119 vga_wseq(regbase, CL_SEQR7,
1120 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1121 control |= 0x2000;
1122 format |= 0x1400;
1123 threshold |= 0x10;
1124 break;
1126 default:
1127 dev_warn(info->device, "unknown Board\n");
1128 break;
1131 /* mode register: 256 color mode */
1132 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1133 #ifdef CONFIG_PCI
1134 WHDR(cinfo, 0xc1); /* Copy Xbh */
1135 #elif defined(CONFIG_ZORRO)
1136 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1137 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1138 #endif
1141 /******************************************************
1143 * 32 bpp
1147 else if (var->bits_per_pixel == 32) {
1148 dev_dbg(info->device, "preparing for 32 bit deep display\n");
1149 switch (cinfo->btype) {
1150 case BT_SD64:
1151 /* Extended Sequencer Mode: 256c col. mode */
1152 vga_wseq(regbase, CL_SEQR7, 0xf9);
1153 /* MCLK select */
1154 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1155 break;
1157 case BT_PICCOLO:
1158 case BT_SPECTRUM:
1159 vga_wseq(regbase, CL_SEQR7, 0x85);
1160 /* Fast Page-Mode writes */
1161 vga_wseq(regbase, CL_SEQRF, 0xb0);
1162 /* MCLK select */
1163 vga_wseq(regbase, CL_SEQR1F, 0x22);
1164 break;
1166 case BT_PICASSO:
1167 vga_wseq(regbase, CL_SEQR7, 0x25);
1168 /* Fast Page-Mode writes */
1169 vga_wseq(regbase, CL_SEQRF, 0xb0);
1170 /* MCLK select */
1171 vga_wseq(regbase, CL_SEQR1F, 0x22);
1172 break;
1174 case BT_PICASSO4:
1175 case BT_ALPINE:
1176 vga_wseq(regbase, CL_SEQR7, 0xa9);
1177 break;
1179 case BT_GD5480:
1180 vga_wseq(regbase, CL_SEQR7, 0x19);
1181 /* We already set SRF and SR1F */
1182 break;
1184 case BT_LAGUNA:
1185 case BT_LAGUNAB:
1186 vga_wseq(regbase, CL_SEQR7,
1187 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1188 control |= 0x6000;
1189 format |= 0x3400;
1190 threshold |= 0x20;
1191 break;
1193 default:
1194 dev_warn(info->device, "unknown Board\n");
1195 break;
1198 /* mode register: 256 color mode */
1199 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1200 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1201 WHDR(cinfo, 0xc5);
1204 /******************************************************
1206 * unknown/unsupported bpp
1210 else
1211 dev_err(info->device,
1212 "What's this? requested color depth == %d.\n",
1213 var->bits_per_pixel);
1215 pitch = info->fix.line_length >> 3;
1216 vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1217 tmp = 0x22;
1218 if (pitch & 0x100)
1219 tmp |= 0x10; /* offset overflow bit */
1221 /* screen start addr #16-18, fastpagemode cycles */
1222 vga_wcrt(regbase, CL_CRT1B, tmp);
1224 /* screen start address bit 19 */
1225 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1226 vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
1228 if (is_laguna(cinfo)) {
1229 tmp = 0;
1230 if ((htotal + 5) & 256)
1231 tmp |= 128;
1232 if (hdispend & 256)
1233 tmp |= 64;
1234 if (hsyncstart & 256)
1235 tmp |= 48;
1236 if (vtotal & 1024)
1237 tmp |= 8;
1238 if (vdispend & 1024)
1239 tmp |= 4;
1240 if (vsyncstart & 1024)
1241 tmp |= 3;
1243 vga_wcrt(regbase, CL_CRT1E, tmp);
1244 dev_dbg(info->device, "CRT1e: %d\n", tmp);
1247 /* pixel panning */
1248 vga_wattr(regbase, CL_AR33, 0);
1250 /* [ EGS: SetOffset(); ] */
1251 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1252 AttrOn(cinfo);
1254 if (is_laguna(cinfo)) {
1255 /* no tiles */
1256 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1257 fb_writew(format, cinfo->laguna_mmio + 0xc0);
1258 fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1260 /* finally, turn on everything - turn off "FullBandwidth" bit */
1261 /* also, set "DotClock%2" bit where requested */
1262 tmp = 0x01;
1264 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1265 if (var->vmode & FB_VMODE_CLOCK_HALVE)
1266 tmp |= 0x08;
1269 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1270 dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1272 #ifdef CIRRUSFB_DEBUG
1273 cirrusfb_dbg_reg_dump(info, NULL);
1274 #endif
1276 return 0;
1279 /* for some reason incomprehensible to me, cirrusfb requires that you write
1280 * the registers twice for the settings to take..grr. -dte */
1281 static int cirrusfb_set_par(struct fb_info *info)
1283 cirrusfb_set_par_foo(info);
1284 return cirrusfb_set_par_foo(info);
1287 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1288 unsigned blue, unsigned transp,
1289 struct fb_info *info)
1291 struct cirrusfb_info *cinfo = info->par;
1293 if (regno > 255)
1294 return -EINVAL;
1296 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1297 u32 v;
1298 red >>= (16 - info->var.red.length);
1299 green >>= (16 - info->var.green.length);
1300 blue >>= (16 - info->var.blue.length);
1302 if (regno >= 16)
1303 return 1;
1304 v = (red << info->var.red.offset) |
1305 (green << info->var.green.offset) |
1306 (blue << info->var.blue.offset);
1308 cinfo->pseudo_palette[regno] = v;
1309 return 0;
1312 if (info->var.bits_per_pixel == 8)
1313 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1315 return 0;
1319 /*************************************************************************
1320 cirrusfb_pan_display()
1322 performs display panning - provided hardware permits this
1323 **************************************************************************/
1324 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1325 struct fb_info *info)
1327 int xoffset;
1328 unsigned long base;
1329 unsigned char tmp, xpix;
1330 struct cirrusfb_info *cinfo = info->par;
1332 dev_dbg(info->device,
1333 "virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1335 /* no range checks for xoffset and yoffset, */
1336 /* as fb_pan_display has already done this */
1337 if (var->vmode & FB_VMODE_YWRAP)
1338 return -EINVAL;
1340 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1342 base = var->yoffset * info->fix.line_length + xoffset;
1344 if (info->var.bits_per_pixel == 1) {
1345 /* base is already correct */
1346 xpix = (unsigned char) (var->xoffset % 8);
1347 } else {
1348 base /= 4;
1349 xpix = (unsigned char) ((xoffset % 4) * 2);
1352 if (!is_laguna(cinfo))
1353 cirrusfb_WaitBLT(cinfo->regbase);
1355 /* lower 8 + 8 bits of screen start address */
1356 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
1357 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
1359 /* 0xf2 is %11110010, exclude tmp bits */
1360 tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1361 /* construct bits 16, 17 and 18 of screen start address */
1362 if (base & 0x10000)
1363 tmp |= 0x01;
1364 if (base & 0x20000)
1365 tmp |= 0x04;
1366 if (base & 0x40000)
1367 tmp |= 0x08;
1369 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1371 /* construct bit 19 of screen start address */
1372 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
1373 tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
1374 if (is_laguna(cinfo))
1375 tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
1376 else
1377 tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
1378 vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
1381 /* write pixel panning value to AR33; this does not quite work in 8bpp
1383 * ### Piccolo..? Will this work?
1385 if (info->var.bits_per_pixel == 1)
1386 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1388 if (!is_laguna(cinfo))
1389 cirrusfb_WaitBLT(cinfo->regbase);
1391 return 0;
1394 static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1397 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1398 * then the caller blanks by setting the CLUT (Color Look Up Table)
1399 * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1400 * failed due to e.g. a video mode which doesn't support it.
1401 * Implements VESA suspend and powerdown modes on hardware that
1402 * supports disabling hsync/vsync:
1403 * blank_mode == 2: suspend vsync
1404 * blank_mode == 3: suspend hsync
1405 * blank_mode == 4: powerdown
1407 unsigned char val;
1408 struct cirrusfb_info *cinfo = info->par;
1409 int current_mode = cinfo->blank_mode;
1411 dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1413 if (info->state != FBINFO_STATE_RUNNING ||
1414 current_mode == blank_mode) {
1415 dev_dbg(info->device, "EXIT, returning 0\n");
1416 return 0;
1419 /* Undo current */
1420 if (current_mode == FB_BLANK_NORMAL ||
1421 current_mode == FB_BLANK_UNBLANK)
1422 /* clear "FullBandwidth" bit */
1423 val = 0;
1424 else
1425 /* set "FullBandwidth" bit */
1426 val = 0x20;
1428 val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1429 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1431 switch (blank_mode) {
1432 case FB_BLANK_UNBLANK:
1433 case FB_BLANK_NORMAL:
1434 val = 0x00;
1435 break;
1436 case FB_BLANK_VSYNC_SUSPEND:
1437 val = 0x04;
1438 break;
1439 case FB_BLANK_HSYNC_SUSPEND:
1440 val = 0x02;
1441 break;
1442 case FB_BLANK_POWERDOWN:
1443 val = 0x06;
1444 break;
1445 default:
1446 dev_dbg(info->device, "EXIT, returning 1\n");
1447 return 1;
1450 vga_wgfx(cinfo->regbase, CL_GRE, val);
1452 cinfo->blank_mode = blank_mode;
1453 dev_dbg(info->device, "EXIT, returning 0\n");
1455 /* Let fbcon do a soft blank for us */
1456 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1459 /**** END Hardware specific Routines **************************************/
1460 /****************************************************************************/
1461 /**** BEGIN Internal Routines ***********************************************/
1463 static void init_vgachip(struct fb_info *info)
1465 struct cirrusfb_info *cinfo = info->par;
1466 const struct cirrusfb_board_info_rec *bi;
1468 assert(cinfo != NULL);
1470 bi = &cirrusfb_board_info[cinfo->btype];
1472 /* reset board globally */
1473 switch (cinfo->btype) {
1474 case BT_PICCOLO:
1475 WSFR(cinfo, 0x01);
1476 udelay(500);
1477 WSFR(cinfo, 0x51);
1478 udelay(500);
1479 break;
1480 case BT_PICASSO:
1481 WSFR2(cinfo, 0xff);
1482 udelay(500);
1483 break;
1484 case BT_SD64:
1485 case BT_SPECTRUM:
1486 WSFR(cinfo, 0x1f);
1487 udelay(500);
1488 WSFR(cinfo, 0x4f);
1489 udelay(500);
1490 break;
1491 case BT_PICASSO4:
1492 /* disable flickerfixer */
1493 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1494 mdelay(100);
1495 /* from Klaus' NetBSD driver: */
1496 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1497 /* put blitter into 542x compat */
1498 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1499 /* mode */
1500 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1501 break;
1503 case BT_GD5480:
1504 /* from Klaus' NetBSD driver: */
1505 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1506 break;
1508 case BT_LAGUNA:
1509 case BT_LAGUNAB:
1510 case BT_ALPINE:
1511 /* Nothing to do to reset the board. */
1512 break;
1514 default:
1515 dev_err(info->device, "Warning: Unknown board type\n");
1516 break;
1519 /* make sure RAM size set by this point */
1520 assert(info->screen_size > 0);
1522 /* the P4 is not fully initialized here; I rely on it having been */
1523 /* inited under AmigaOS already, which seems to work just fine */
1524 /* (Klaus advised to do it this way) */
1526 if (cinfo->btype != BT_PICASSO4) {
1527 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1528 WGen(cinfo, CL_POS102, 0x01);
1529 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1531 if (cinfo->btype != BT_SD64)
1532 WGen(cinfo, CL_VSSM2, 0x01);
1534 /* reset sequencer logic */
1535 vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1537 /* FullBandwidth (video off) and 8/9 dot clock */
1538 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1540 /* "magic cookie" - doesn't make any sense to me.. */
1541 /* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1542 /* unlock all extension registers */
1543 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1545 switch (cinfo->btype) {
1546 case BT_GD5480:
1547 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1548 break;
1549 case BT_ALPINE:
1550 case BT_LAGUNA:
1551 case BT_LAGUNAB:
1552 break;
1553 case BT_SD64:
1554 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1555 break;
1556 default:
1557 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1558 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1559 break;
1562 /* plane mask: nothing */
1563 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1564 /* character map select: doesn't even matter in gx mode */
1565 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1566 /* memory mode: chain4, ext. memory */
1567 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1569 /* controller-internal base address of video memory */
1570 if (bi->init_sr07)
1571 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1573 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1574 /* EEPROM control: shouldn't be necessary to write to this at all.. */
1576 /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1577 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1578 /* graphics cursor Y position (..."... ) */
1579 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1580 /* graphics cursor attributes */
1581 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1582 /* graphics cursor pattern address */
1583 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1585 /* writing these on a P4 might give problems.. */
1586 if (cinfo->btype != BT_PICASSO4) {
1587 /* configuration readback and ext. color */
1588 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1589 /* signature generator */
1590 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1593 /* MCLK select etc. */
1594 if (bi->init_sr1f)
1595 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1597 /* Screen A preset row scan: none */
1598 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1599 /* Text cursor start: disable text cursor */
1600 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1601 /* Text cursor end: - */
1602 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1603 /* text cursor location high: 0 */
1604 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1605 /* text cursor location low: 0 */
1606 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1608 /* Underline Row scanline: - */
1609 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1610 /* ### add 0x40 for text modes with > 30 MHz pixclock */
1611 /* ext. display controls: ext.adr. wrap */
1612 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1614 /* Set/Reset registes: - */
1615 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1616 /* Set/Reset enable: - */
1617 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1618 /* Color Compare: - */
1619 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1620 /* Data Rotate: - */
1621 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1622 /* Read Map Select: - */
1623 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1624 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1625 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1626 /* Miscellaneous: memory map base address, graphics mode */
1627 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1628 /* Color Don't care: involve all planes */
1629 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1630 /* Bit Mask: no mask at all */
1631 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1633 if (cinfo->btype == BT_ALPINE || is_laguna(cinfo))
1634 /* (5434 can't have bit 3 set for bitblt) */
1635 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1636 else
1637 /* Graphics controller mode extensions: finer granularity,
1638 * 8byte data latches
1640 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1642 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1643 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1644 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1645 /* Background color byte 1: - */
1646 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1647 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1649 /* Attribute Controller palette registers: "identity mapping" */
1650 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1651 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1652 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1653 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1654 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1655 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1656 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1657 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1658 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1659 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1660 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1661 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1662 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1663 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1664 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1665 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1667 /* Attribute Controller mode: graphics mode */
1668 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1669 /* Overscan color reg.: reg. 0 */
1670 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1671 /* Color Plane enable: Enable all 4 planes */
1672 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1673 /* Color Select: - */
1674 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1676 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1678 /* BLT Start/status: Blitter reset */
1679 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1680 /* - " - : "end-of-reset" */
1681 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1683 /* misc... */
1684 WHDR(cinfo, 0); /* Hidden DAC register: - */
1685 return;
1688 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1690 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1691 static int IsOn = 0; /* XXX not ok for multiple boards */
1693 if (cinfo->btype == BT_PICASSO4)
1694 return; /* nothing to switch */
1695 if (cinfo->btype == BT_ALPINE)
1696 return; /* nothing to switch */
1697 if (cinfo->btype == BT_GD5480)
1698 return; /* nothing to switch */
1699 if (cinfo->btype == BT_PICASSO) {
1700 if ((on && !IsOn) || (!on && IsOn))
1701 WSFR(cinfo, 0xff);
1702 return;
1704 if (on) {
1705 switch (cinfo->btype) {
1706 case BT_SD64:
1707 WSFR(cinfo, cinfo->SFR | 0x21);
1708 break;
1709 case BT_PICCOLO:
1710 WSFR(cinfo, cinfo->SFR | 0x28);
1711 break;
1712 case BT_SPECTRUM:
1713 WSFR(cinfo, 0x6f);
1714 break;
1715 default: /* do nothing */ break;
1717 } else {
1718 switch (cinfo->btype) {
1719 case BT_SD64:
1720 WSFR(cinfo, cinfo->SFR & 0xde);
1721 break;
1722 case BT_PICCOLO:
1723 WSFR(cinfo, cinfo->SFR & 0xd7);
1724 break;
1725 case BT_SPECTRUM:
1726 WSFR(cinfo, 0x4f);
1727 break;
1728 default: /* do nothing */
1729 break;
1732 #endif /* CONFIG_ZORRO */
1735 /******************************************/
1736 /* Linux 2.6-style accelerated functions */
1737 /******************************************/
1739 static int cirrusfb_sync(struct fb_info *info)
1741 struct cirrusfb_info *cinfo = info->par;
1743 if (!is_laguna(cinfo)) {
1744 while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1745 cpu_relax();
1747 return 0;
1750 static void cirrusfb_fillrect(struct fb_info *info,
1751 const struct fb_fillrect *region)
1753 struct fb_fillrect modded;
1754 int vxres, vyres;
1755 struct cirrusfb_info *cinfo = info->par;
1756 int m = info->var.bits_per_pixel;
1757 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1758 cinfo->pseudo_palette[region->color] : region->color;
1760 if (info->state != FBINFO_STATE_RUNNING)
1761 return;
1762 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1763 cfb_fillrect(info, region);
1764 return;
1767 vxres = info->var.xres_virtual;
1768 vyres = info->var.yres_virtual;
1770 memcpy(&modded, region, sizeof(struct fb_fillrect));
1772 if (!modded.width || !modded.height ||
1773 modded.dx >= vxres || modded.dy >= vyres)
1774 return;
1776 if (modded.dx + modded.width > vxres)
1777 modded.width = vxres - modded.dx;
1778 if (modded.dy + modded.height > vyres)
1779 modded.height = vyres - modded.dy;
1781 cirrusfb_RectFill(cinfo->regbase,
1782 info->var.bits_per_pixel,
1783 (region->dx * m) / 8, region->dy,
1784 (region->width * m) / 8, region->height,
1785 color, color,
1786 info->fix.line_length, 0x40);
1789 static void cirrusfb_copyarea(struct fb_info *info,
1790 const struct fb_copyarea *area)
1792 struct fb_copyarea modded;
1793 u32 vxres, vyres;
1794 struct cirrusfb_info *cinfo = info->par;
1795 int m = info->var.bits_per_pixel;
1797 if (info->state != FBINFO_STATE_RUNNING)
1798 return;
1799 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1800 cfb_copyarea(info, area);
1801 return;
1804 vxres = info->var.xres_virtual;
1805 vyres = info->var.yres_virtual;
1806 memcpy(&modded, area, sizeof(struct fb_copyarea));
1808 if (!modded.width || !modded.height ||
1809 modded.sx >= vxres || modded.sy >= vyres ||
1810 modded.dx >= vxres || modded.dy >= vyres)
1811 return;
1813 if (modded.sx + modded.width > vxres)
1814 modded.width = vxres - modded.sx;
1815 if (modded.dx + modded.width > vxres)
1816 modded.width = vxres - modded.dx;
1817 if (modded.sy + modded.height > vyres)
1818 modded.height = vyres - modded.sy;
1819 if (modded.dy + modded.height > vyres)
1820 modded.height = vyres - modded.dy;
1822 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1823 (area->sx * m) / 8, area->sy,
1824 (area->dx * m) / 8, area->dy,
1825 (area->width * m) / 8, area->height,
1826 info->fix.line_length);
1830 static void cirrusfb_imageblit(struct fb_info *info,
1831 const struct fb_image *image)
1833 struct cirrusfb_info *cinfo = info->par;
1835 if (info->state != FBINFO_STATE_RUNNING)
1836 return;
1837 if (info->flags & FBINFO_HWACCEL_DISABLED)
1838 cfb_imageblit(info, image);
1839 else {
1840 unsigned size = ((image->width + 7) >> 3) * image->height;
1841 int m = info->var.bits_per_pixel;
1842 u32 fg, bg;
1844 if (info->var.bits_per_pixel == 8) {
1845 fg = image->fg_color;
1846 bg = image->bg_color;
1847 } else {
1848 fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1849 bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1851 cirrusfb_WaitBLT(cinfo->regbase);
1852 /* byte rounded scanlines */
1853 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1854 cirrusfb_RectFill(cinfo->regbase,
1855 info->var.bits_per_pixel,
1856 (image->dx * m) / 8, image->dy,
1857 (image->width * m) / 8, image->height,
1858 fg, bg,
1859 info->fix.line_length, 0x04);
1860 memcpy(info->screen_base, image->data, size);
1864 #ifdef CONFIG_PPC_PREP
1865 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1866 #define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
1867 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1869 *display = PREP_VIDEO_BASE;
1870 *registers = (unsigned long) PREP_IO_BASE;
1873 #endif /* CONFIG_PPC_PREP */
1875 #ifdef CONFIG_PCI
1876 static int release_io_ports;
1878 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1879 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
1880 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1881 * seem to have. */
1882 static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1883 u8 __iomem *regbase)
1885 unsigned long mem;
1886 struct cirrusfb_info *cinfo = info->par;
1888 if (is_laguna(cinfo)) {
1889 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1891 mem = ((SR14 & 7) + 1) << 20;
1892 } else {
1893 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1894 switch ((SRF & 0x18)) {
1895 case 0x08:
1896 mem = 512 * 1024;
1897 break;
1898 case 0x10:
1899 mem = 1024 * 1024;
1900 break;
1901 /* 64-bit DRAM data bus width; assume 2MB.
1902 * Also indicates 2MB memory on the 5430.
1904 case 0x18:
1905 mem = 2048 * 1024;
1906 break;
1907 default:
1908 dev_warn(info->device, "Unknown memory size!\n");
1909 mem = 1024 * 1024;
1911 /* If DRAM bank switching is enabled, there must be
1912 * twice as much memory installed. (4MB on the 5434)
1914 if (SRF & 0x80)
1915 mem *= 2;
1918 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1919 return mem;
1922 static void get_pci_addrs(const struct pci_dev *pdev,
1923 unsigned long *display, unsigned long *registers)
1925 assert(pdev != NULL);
1926 assert(display != NULL);
1927 assert(registers != NULL);
1929 *display = 0;
1930 *registers = 0;
1932 /* This is a best-guess for now */
1934 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1935 *display = pci_resource_start(pdev, 1);
1936 *registers = pci_resource_start(pdev, 0);
1937 } else {
1938 *display = pci_resource_start(pdev, 0);
1939 *registers = pci_resource_start(pdev, 1);
1942 assert(*display != 0);
1945 static void cirrusfb_pci_unmap(struct fb_info *info)
1947 struct pci_dev *pdev = to_pci_dev(info->device);
1948 struct cirrusfb_info *cinfo = info->par;
1950 if (cinfo->laguna_mmio == NULL)
1951 iounmap(cinfo->laguna_mmio);
1952 iounmap(info->screen_base);
1953 #if 0 /* if system didn't claim this region, we would... */
1954 release_mem_region(0xA0000, 65535);
1955 #endif
1956 if (release_io_ports)
1957 release_region(0x3C0, 32);
1958 pci_release_regions(pdev);
1960 #endif /* CONFIG_PCI */
1962 #ifdef CONFIG_ZORRO
1963 static void cirrusfb_zorro_unmap(struct fb_info *info)
1965 struct cirrusfb_info *cinfo = info->par;
1966 struct zorro_dev *zdev = to_zorro_dev(info->device);
1968 zorro_release_device(zdev);
1970 if (cinfo->btype == BT_PICASSO4) {
1971 cinfo->regbase -= 0x600000;
1972 iounmap((void *)cinfo->regbase);
1973 iounmap(info->screen_base);
1974 } else {
1975 if (zorro_resource_start(zdev) > 0x01000000)
1976 iounmap(info->screen_base);
1979 #endif /* CONFIG_ZORRO */
1981 /* function table of the above functions */
1982 static struct fb_ops cirrusfb_ops = {
1983 .owner = THIS_MODULE,
1984 .fb_open = cirrusfb_open,
1985 .fb_release = cirrusfb_release,
1986 .fb_setcolreg = cirrusfb_setcolreg,
1987 .fb_check_var = cirrusfb_check_var,
1988 .fb_set_par = cirrusfb_set_par,
1989 .fb_pan_display = cirrusfb_pan_display,
1990 .fb_blank = cirrusfb_blank,
1991 .fb_fillrect = cirrusfb_fillrect,
1992 .fb_copyarea = cirrusfb_copyarea,
1993 .fb_sync = cirrusfb_sync,
1994 .fb_imageblit = cirrusfb_imageblit,
1997 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
1999 struct cirrusfb_info *cinfo = info->par;
2000 struct fb_var_screeninfo *var = &info->var;
2002 info->pseudo_palette = cinfo->pseudo_palette;
2003 info->flags = FBINFO_DEFAULT
2004 | FBINFO_HWACCEL_XPAN
2005 | FBINFO_HWACCEL_YPAN
2006 | FBINFO_HWACCEL_FILLRECT
2007 | FBINFO_HWACCEL_IMAGEBLIT
2008 | FBINFO_HWACCEL_COPYAREA;
2009 if (noaccel || is_laguna(cinfo))
2010 info->flags |= FBINFO_HWACCEL_DISABLED;
2011 info->fbops = &cirrusfb_ops;
2013 if (cinfo->btype == BT_GD5480) {
2014 if (var->bits_per_pixel == 16)
2015 info->screen_base += 1 * MB_;
2016 if (var->bits_per_pixel == 32)
2017 info->screen_base += 2 * MB_;
2020 /* Fill fix common fields */
2021 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2022 sizeof(info->fix.id));
2024 /* monochrome: only 1 memory plane */
2025 /* 8 bit and above: Use whole memory area */
2026 info->fix.smem_len = info->screen_size;
2027 if (var->bits_per_pixel == 1)
2028 info->fix.smem_len /= 4;
2029 info->fix.type_aux = 0;
2030 info->fix.xpanstep = 1;
2031 info->fix.ypanstep = 1;
2032 info->fix.ywrapstep = 0;
2034 /* FIXME: map region at 0xB8000 if available, fill in here */
2035 info->fix.mmio_len = 0;
2036 info->fix.accel = FB_ACCEL_NONE;
2038 fb_alloc_cmap(&info->cmap, 256, 0);
2040 return 0;
2043 static int __devinit cirrusfb_register(struct fb_info *info)
2045 struct cirrusfb_info *cinfo = info->par;
2046 int err;
2048 /* sanity checks */
2049 assert(cinfo->btype != BT_NONE);
2051 /* set all the vital stuff */
2052 cirrusfb_set_fbinfo(info);
2054 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2056 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2057 if (!err) {
2058 dev_dbg(info->device, "wrong initial video mode\n");
2059 err = -EINVAL;
2060 goto err_dealloc_cmap;
2063 info->var.activate = FB_ACTIVATE_NOW;
2065 err = cirrusfb_check_var(&info->var, info);
2066 if (err < 0) {
2067 /* should never happen */
2068 dev_dbg(info->device,
2069 "choking on default var... umm, no good.\n");
2070 goto err_dealloc_cmap;
2073 err = register_framebuffer(info);
2074 if (err < 0) {
2075 dev_err(info->device,
2076 "could not register fb device; err = %d!\n", err);
2077 goto err_dealloc_cmap;
2080 return 0;
2082 err_dealloc_cmap:
2083 fb_dealloc_cmap(&info->cmap);
2084 return err;
2087 static void __devexit cirrusfb_cleanup(struct fb_info *info)
2089 struct cirrusfb_info *cinfo = info->par;
2091 switch_monitor(cinfo, 0);
2092 unregister_framebuffer(info);
2093 fb_dealloc_cmap(&info->cmap);
2094 dev_dbg(info->device, "Framebuffer unregistered\n");
2095 cinfo->unmap(info);
2096 framebuffer_release(info);
2099 #ifdef CONFIG_PCI
2100 static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2101 const struct pci_device_id *ent)
2103 struct cirrusfb_info *cinfo;
2104 struct fb_info *info;
2105 unsigned long board_addr, board_size;
2106 int ret;
2108 ret = pci_enable_device(pdev);
2109 if (ret < 0) {
2110 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2111 goto err_out;
2114 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2115 if (!info) {
2116 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2117 ret = -ENOMEM;
2118 goto err_out;
2121 cinfo = info->par;
2122 cinfo->btype = (enum cirrus_board) ent->driver_data;
2124 dev_dbg(info->device,
2125 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2126 (unsigned long long)pdev->resource[0].start, cinfo->btype);
2127 dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2128 (unsigned long long)pdev->resource[1].start);
2130 if (isPReP) {
2131 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2132 #ifdef CONFIG_PPC_PREP
2133 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2134 #endif
2135 /* PReP dies if we ioremap the IO registers, but it works w/out... */
2136 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2137 } else {
2138 dev_dbg(info->device,
2139 "Attempt to get PCI info for Cirrus Graphics Card\n");
2140 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2141 /* FIXME: this forces VGA. alternatives? */
2142 cinfo->regbase = NULL;
2143 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2146 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2147 board_addr, info->fix.mmio_start);
2149 board_size = (cinfo->btype == BT_GD5480) ?
2150 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2152 ret = pci_request_regions(pdev, "cirrusfb");
2153 if (ret < 0) {
2154 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2155 board_addr);
2156 goto err_release_fb;
2158 #if 0 /* if the system didn't claim this region, we would... */
2159 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2160 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2161 0xA0000L);
2162 ret = -EBUSY;
2163 goto err_release_regions;
2165 #endif
2166 if (request_region(0x3C0, 32, "cirrusfb"))
2167 release_io_ports = 1;
2169 info->screen_base = ioremap(board_addr, board_size);
2170 if (!info->screen_base) {
2171 ret = -EIO;
2172 goto err_release_legacy;
2175 info->fix.smem_start = board_addr;
2176 info->screen_size = board_size;
2177 cinfo->unmap = cirrusfb_pci_unmap;
2179 dev_info(info->device,
2180 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2181 info->screen_size >> 10, board_addr);
2182 pci_set_drvdata(pdev, info);
2184 ret = cirrusfb_register(info);
2185 if (!ret)
2186 return 0;
2188 pci_set_drvdata(pdev, NULL);
2189 iounmap(info->screen_base);
2190 err_release_legacy:
2191 if (release_io_ports)
2192 release_region(0x3C0, 32);
2193 #if 0
2194 release_mem_region(0xA0000, 65535);
2195 err_release_regions:
2196 #endif
2197 pci_release_regions(pdev);
2198 err_release_fb:
2199 if (cinfo->laguna_mmio != NULL)
2200 iounmap(cinfo->laguna_mmio);
2201 framebuffer_release(info);
2202 err_out:
2203 return ret;
2206 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2208 struct fb_info *info = pci_get_drvdata(pdev);
2210 cirrusfb_cleanup(info);
2213 static struct pci_driver cirrusfb_pci_driver = {
2214 .name = "cirrusfb",
2215 .id_table = cirrusfb_pci_table,
2216 .probe = cirrusfb_pci_register,
2217 .remove = __devexit_p(cirrusfb_pci_unregister),
2218 #ifdef CONFIG_PM
2219 #if 0
2220 .suspend = cirrusfb_pci_suspend,
2221 .resume = cirrusfb_pci_resume,
2222 #endif
2223 #endif
2225 #endif /* CONFIG_PCI */
2227 #ifdef CONFIG_ZORRO
2228 static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2229 const struct zorro_device_id *ent)
2231 struct cirrusfb_info *cinfo;
2232 struct fb_info *info;
2233 enum cirrus_board btype;
2234 struct zorro_dev *z2 = NULL;
2235 unsigned long board_addr, board_size, size;
2236 int ret;
2238 btype = ent->driver_data;
2239 if (cirrusfb_zorro_table2[btype].id2)
2240 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2241 size = cirrusfb_zorro_table2[btype].size;
2243 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2244 if (!info) {
2245 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2246 ret = -ENOMEM;
2247 goto err_out;
2250 dev_info(info->device, "%s board detected\n",
2251 cirrusfb_board_info[btype].name);
2253 cinfo = info->par;
2254 cinfo->btype = btype;
2256 assert(z);
2257 assert(btype != BT_NONE);
2259 board_addr = zorro_resource_start(z);
2260 board_size = zorro_resource_len(z);
2261 info->screen_size = size;
2263 if (!zorro_request_device(z, "cirrusfb")) {
2264 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2265 board_addr);
2266 ret = -EBUSY;
2267 goto err_release_fb;
2270 ret = -EIO;
2272 if (btype == BT_PICASSO4) {
2273 dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
2275 /* To be precise, for the P4 this is not the */
2276 /* begin of the board, but the begin of RAM. */
2277 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2278 /* (note the ugly hardcoded 16M number) */
2279 cinfo->regbase = ioremap(board_addr, 16777216);
2280 if (!cinfo->regbase)
2281 goto err_release_region;
2283 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2284 cinfo->regbase);
2285 cinfo->regbase += 0x600000;
2286 info->fix.mmio_start = board_addr + 0x600000;
2288 info->fix.smem_start = board_addr + 16777216;
2289 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2290 if (!info->screen_base)
2291 goto err_unmap_regbase;
2292 } else {
2293 dev_info(info->device, " REG at $%lx\n",
2294 (unsigned long) z2->resource.start);
2296 info->fix.smem_start = board_addr;
2297 if (board_addr > 0x01000000)
2298 info->screen_base = ioremap(board_addr, board_size);
2299 else
2300 info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2301 if (!info->screen_base)
2302 goto err_release_region;
2304 /* set address for REG area of board */
2305 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2306 info->fix.mmio_start = z2->resource.start;
2308 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2309 cinfo->regbase);
2311 cinfo->unmap = cirrusfb_zorro_unmap;
2313 dev_info(info->device,
2314 "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
2315 board_size / MB_, board_addr);
2317 zorro_set_drvdata(z, info);
2319 ret = cirrusfb_register(info);
2320 if (!ret)
2321 return 0;
2323 if (btype == BT_PICASSO4 || board_addr > 0x01000000)
2324 iounmap(info->screen_base);
2326 err_unmap_regbase:
2327 if (btype == BT_PICASSO4)
2328 iounmap(cinfo->regbase - 0x600000);
2329 err_release_region:
2330 release_region(board_addr, board_size);
2331 err_release_fb:
2332 framebuffer_release(info);
2333 err_out:
2334 return ret;
2337 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2339 struct fb_info *info = zorro_get_drvdata(z);
2341 cirrusfb_cleanup(info);
2344 static struct zorro_driver cirrusfb_zorro_driver = {
2345 .name = "cirrusfb",
2346 .id_table = cirrusfb_zorro_table,
2347 .probe = cirrusfb_zorro_register,
2348 .remove = __devexit_p(cirrusfb_zorro_unregister),
2350 #endif /* CONFIG_ZORRO */
2352 #ifndef MODULE
2353 static int __init cirrusfb_setup(char *options)
2355 char *this_opt;
2357 if (!options || !*options)
2358 return 0;
2360 while ((this_opt = strsep(&options, ",")) != NULL) {
2361 if (!*this_opt)
2362 continue;
2364 if (!strcmp(this_opt, "noaccel"))
2365 noaccel = 1;
2366 else if (!strncmp(this_opt, "mode:", 5))
2367 mode_option = this_opt + 5;
2368 else
2369 mode_option = this_opt;
2371 return 0;
2373 #endif
2376 * Modularization
2379 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2380 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2381 MODULE_LICENSE("GPL");
2383 static int __init cirrusfb_init(void)
2385 int error = 0;
2387 #ifndef MODULE
2388 char *option = NULL;
2390 if (fb_get_options("cirrusfb", &option))
2391 return -ENODEV;
2392 cirrusfb_setup(option);
2393 #endif
2395 #ifdef CONFIG_ZORRO
2396 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2397 #endif
2398 #ifdef CONFIG_PCI
2399 error |= pci_register_driver(&cirrusfb_pci_driver);
2400 #endif
2401 return error;
2404 static void __exit cirrusfb_exit(void)
2406 #ifdef CONFIG_PCI
2407 pci_unregister_driver(&cirrusfb_pci_driver);
2408 #endif
2409 #ifdef CONFIG_ZORRO
2410 zorro_unregister_driver(&cirrusfb_zorro_driver);
2411 #endif
2414 module_init(cirrusfb_init);
2416 module_param(mode_option, charp, 0);
2417 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2418 module_param(noaccel, bool, 0);
2419 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2421 #ifdef MODULE
2422 module_exit(cirrusfb_exit);
2423 #endif
2425 /**********************************************************************/
2426 /* about the following functions - I have used the same names for the */
2427 /* functions as Markus Wild did in his Retina driver for NetBSD as */
2428 /* they just made sense for this purpose. Apart from that, I wrote */
2429 /* these functions myself. */
2430 /**********************************************************************/
2432 /*** WGen() - write into one of the external/general registers ***/
2433 static void WGen(const struct cirrusfb_info *cinfo,
2434 int regnum, unsigned char val)
2436 unsigned long regofs = 0;
2438 if (cinfo->btype == BT_PICASSO) {
2439 /* Picasso II specific hack */
2440 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2441 regnum == CL_VSSM2) */
2442 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2443 regofs = 0xfff;
2446 vga_w(cinfo->regbase, regofs + regnum, val);
2449 /*** RGen() - read out one of the external/general registers ***/
2450 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2452 unsigned long regofs = 0;
2454 if (cinfo->btype == BT_PICASSO) {
2455 /* Picasso II specific hack */
2456 /* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2457 regnum == CL_VSSM2) */
2458 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2459 regofs = 0xfff;
2462 return vga_r(cinfo->regbase, regofs + regnum);
2465 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2466 static void AttrOn(const struct cirrusfb_info *cinfo)
2468 assert(cinfo != NULL);
2470 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2471 /* if we're just in "write value" mode, write back the */
2472 /* same value as before to not modify anything */
2473 vga_w(cinfo->regbase, VGA_ATT_IW,
2474 vga_r(cinfo->regbase, VGA_ATT_R));
2476 /* turn on video bit */
2477 /* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2478 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2480 /* dummy write on Reg0 to be on "write index" mode next time */
2481 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2484 /*** WHDR() - write into the Hidden DAC register ***/
2485 /* as the HDR is the only extension register that requires special treatment
2486 * (the other extension registers are accessible just like the "ordinary"
2487 * registers of their functional group) here is a specialized routine for
2488 * accessing the HDR
2490 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2492 unsigned char dummy;
2494 if (is_laguna(cinfo))
2495 return;
2496 if (cinfo->btype == BT_PICASSO) {
2497 /* Klaus' hint for correct access to HDR on some boards */
2498 /* first write 0 to pixel mask (3c6) */
2499 WGen(cinfo, VGA_PEL_MSK, 0x00);
2500 udelay(200);
2501 /* next read dummy from pixel address (3c8) */
2502 dummy = RGen(cinfo, VGA_PEL_IW);
2503 udelay(200);
2505 /* now do the usual stuff to access the HDR */
2507 dummy = RGen(cinfo, VGA_PEL_MSK);
2508 udelay(200);
2509 dummy = RGen(cinfo, VGA_PEL_MSK);
2510 udelay(200);
2511 dummy = RGen(cinfo, VGA_PEL_MSK);
2512 udelay(200);
2513 dummy = RGen(cinfo, VGA_PEL_MSK);
2514 udelay(200);
2516 WGen(cinfo, VGA_PEL_MSK, val);
2517 udelay(200);
2519 if (cinfo->btype == BT_PICASSO) {
2520 /* now first reset HDR access counter */
2521 dummy = RGen(cinfo, VGA_PEL_IW);
2522 udelay(200);
2524 /* and at the end, restore the mask value */
2525 /* ## is this mask always 0xff? */
2526 WGen(cinfo, VGA_PEL_MSK, 0xff);
2527 udelay(200);
2531 /*** WSFR() - write to the "special function register" (SFR) ***/
2532 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2534 #ifdef CONFIG_ZORRO
2535 assert(cinfo->regbase != NULL);
2536 cinfo->SFR = val;
2537 z_writeb(val, cinfo->regbase + 0x8000);
2538 #endif
2541 /* The Picasso has a second register for switching the monitor bit */
2542 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2544 #ifdef CONFIG_ZORRO
2545 /* writing an arbitrary value to this one causes the monitor switcher */
2546 /* to flip to Amiga display */
2547 assert(cinfo->regbase != NULL);
2548 cinfo->SFR = val;
2549 z_writeb(val, cinfo->regbase + 0x9000);
2550 #endif
2553 /*** WClut - set CLUT entry (range: 0..63) ***/
2554 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2555 unsigned char green, unsigned char blue)
2557 unsigned int data = VGA_PEL_D;
2559 /* address write mode register is not translated.. */
2560 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2562 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2563 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2564 is_laguna(cinfo)) {
2565 /* but DAC data register IS, at least for Picasso II */
2566 if (cinfo->btype == BT_PICASSO)
2567 data += 0xfff;
2568 vga_w(cinfo->regbase, data, red);
2569 vga_w(cinfo->regbase, data, green);
2570 vga_w(cinfo->regbase, data, blue);
2571 } else {
2572 vga_w(cinfo->regbase, data, blue);
2573 vga_w(cinfo->regbase, data, green);
2574 vga_w(cinfo->regbase, data, red);
2578 #if 0
2579 /*** RClut - read CLUT entry (range 0..63) ***/
2580 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2581 unsigned char *green, unsigned char *blue)
2583 unsigned int data = VGA_PEL_D;
2585 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2587 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2588 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2589 if (cinfo->btype == BT_PICASSO)
2590 data += 0xfff;
2591 *red = vga_r(cinfo->regbase, data);
2592 *green = vga_r(cinfo->regbase, data);
2593 *blue = vga_r(cinfo->regbase, data);
2594 } else {
2595 *blue = vga_r(cinfo->regbase, data);
2596 *green = vga_r(cinfo->regbase, data);
2597 *red = vga_r(cinfo->regbase, data);
2600 #endif
2602 /*******************************************************************
2603 cirrusfb_WaitBLT()
2605 Wait for the BitBLT engine to complete a possible earlier job
2606 *********************************************************************/
2608 /* FIXME: use interrupts instead */
2609 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2611 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2612 cpu_relax();
2615 /*******************************************************************
2616 cirrusfb_BitBLT()
2618 perform accelerated "scrolling"
2619 ********************************************************************/
2621 static void cirrusfb_set_blitter(u8 __iomem *regbase,
2622 u_short nwidth, u_short nheight,
2623 u_long nsrc, u_long ndest,
2624 u_short bltmode, u_short line_length)
2627 /* pitch: set to line_length */
2628 /* dest pitch low */
2629 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2630 /* dest pitch hi */
2631 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2632 /* source pitch low */
2633 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2634 /* source pitch hi */
2635 vga_wgfx(regbase, CL_GR27, line_length >> 8);
2637 /* BLT width: actual number of pixels - 1 */
2638 /* BLT width low */
2639 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2640 /* BLT width hi */
2641 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2643 /* BLT height: actual number of lines -1 */
2644 /* BLT height low */
2645 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2646 /* BLT width hi */
2647 vga_wgfx(regbase, CL_GR23, nheight >> 8);
2649 /* BLT destination */
2650 /* BLT dest low */
2651 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2652 /* BLT dest mid */
2653 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2654 /* BLT dest hi */
2655 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2657 /* BLT source */
2658 /* BLT src low */
2659 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2660 /* BLT src mid */
2661 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2662 /* BLT src hi */
2663 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2665 /* BLT mode */
2666 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
2668 /* BLT ROP: SrcCopy */
2669 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2671 /* and finally: GO! */
2672 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2675 /*******************************************************************
2676 cirrusfb_BitBLT()
2678 perform accelerated "scrolling"
2679 ********************************************************************/
2681 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2682 u_short curx, u_short cury,
2683 u_short destx, u_short desty,
2684 u_short width, u_short height,
2685 u_short line_length)
2687 u_short nwidth = width - 1;
2688 u_short nheight = height - 1;
2689 u_long nsrc, ndest;
2690 u_char bltmode;
2692 bltmode = 0x00;
2693 /* if source adr < dest addr, do the Blt backwards */
2694 if (cury <= desty) {
2695 if (cury == desty) {
2696 /* if src and dest are on the same line, check x */
2697 if (curx < destx)
2698 bltmode |= 0x01;
2699 } else
2700 bltmode |= 0x01;
2702 /* standard case: forward blitting */
2703 nsrc = (cury * line_length) + curx;
2704 ndest = (desty * line_length) + destx;
2705 if (bltmode) {
2706 /* this means start addresses are at the end,
2707 * counting backwards
2709 nsrc += nheight * line_length + nwidth;
2710 ndest += nheight * line_length + nwidth;
2713 cirrusfb_WaitBLT(regbase);
2715 cirrusfb_set_blitter(regbase, nwidth, nheight,
2716 nsrc, ndest, bltmode, line_length);
2719 /*******************************************************************
2720 cirrusfb_RectFill()
2722 perform accelerated rectangle fill
2723 ********************************************************************/
2725 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2726 u_short x, u_short y, u_short width, u_short height,
2727 u32 fg_color, u32 bg_color, u_short line_length,
2728 u_char blitmode)
2730 u_long ndest = (y * line_length) + x;
2731 u_char op;
2733 cirrusfb_WaitBLT(regbase);
2735 /* This is a ColorExpand Blt, using the */
2736 /* same color for foreground and background */
2737 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2738 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2740 op = 0x80;
2741 if (bits_per_pixel >= 16) {
2742 vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2743 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2744 op = 0x90;
2746 if (bits_per_pixel == 32) {
2747 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2748 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2749 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2750 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2751 op = 0xb0;
2753 cirrusfb_set_blitter(regbase, width - 1, height - 1,
2754 0, ndest, op | blitmode, line_length);
2757 /**************************************************************************
2758 * bestclock() - determine closest possible clock lower(?) than the
2759 * desired pixel clock
2760 **************************************************************************/
2761 static void bestclock(long freq, int *nom, int *den, int *div)
2763 int n, d;
2764 long h, diff;
2766 assert(nom != NULL);
2767 assert(den != NULL);
2768 assert(div != NULL);
2770 *nom = 0;
2771 *den = 0;
2772 *div = 0;
2774 if (freq < 8000)
2775 freq = 8000;
2777 diff = freq;
2779 for (n = 32; n < 128; n++) {
2780 int s = 0;
2782 d = (14318 * n) / freq;
2783 if ((d >= 7) && (d <= 63)) {
2784 int temp = d;
2786 if (temp > 31) {
2787 s = 1;
2788 temp >>= 1;
2790 h = ((14318 * n) / temp) >> s;
2791 h = h > freq ? h - freq : freq - h;
2792 if (h < diff) {
2793 diff = h;
2794 *nom = n;
2795 *den = temp;
2796 *div = s;
2799 d++;
2800 if ((d >= 7) && (d <= 63)) {
2801 if (d > 31) {
2802 s = 1;
2803 d >>= 1;
2805 h = ((14318 * n) / d) >> s;
2806 h = h > freq ? h - freq : freq - h;
2807 if (h < diff) {
2808 diff = h;
2809 *nom = n;
2810 *den = d;
2811 *div = s;
2817 /* -------------------------------------------------------------------------
2819 * debugging functions
2821 * -------------------------------------------------------------------------
2824 #ifdef CIRRUSFB_DEBUG
2827 * cirrusfb_dbg_print_regs
2828 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2829 * @reg_class: type of registers to read: %CRT, or %SEQ
2831 * DESCRIPTION:
2832 * Dumps the given list of VGA CRTC registers. If @base is %NULL,
2833 * old-style I/O ports are queried for information, otherwise MMIO is
2834 * used at the given @base address to query the information.
2837 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2838 caddr_t regbase,
2839 enum cirrusfb_dbg_reg_class reg_class, ...)
2841 va_list list;
2842 unsigned char val = 0;
2843 unsigned reg;
2844 char *name;
2846 va_start(list, reg_class);
2848 name = va_arg(list, char *);
2849 while (name != NULL) {
2850 reg = va_arg(list, int);
2852 switch (reg_class) {
2853 case CRT:
2854 val = vga_rcrt(regbase, (unsigned char) reg);
2855 break;
2856 case SEQ:
2857 val = vga_rseq(regbase, (unsigned char) reg);
2858 break;
2859 default:
2860 /* should never occur */
2861 assert(false);
2862 break;
2865 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2867 name = va_arg(list, char *);
2870 va_end(list);
2874 * cirrusfb_dbg_reg_dump
2875 * @base: If using newmmio, the newmmio base address, otherwise %NULL
2877 * DESCRIPTION:
2878 * Dumps a list of interesting VGA and CIRRUSFB registers. If @base is %NULL,
2879 * old-style I/O ports are queried for information, otherwise MMIO is
2880 * used at the given @base address to query the information.
2883 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2885 dev_dbg(info->device, "VGA CRTC register dump:\n");
2887 cirrusfb_dbg_print_regs(info, regbase, CRT,
2888 "CR00", 0x00,
2889 "CR01", 0x01,
2890 "CR02", 0x02,
2891 "CR03", 0x03,
2892 "CR04", 0x04,
2893 "CR05", 0x05,
2894 "CR06", 0x06,
2895 "CR07", 0x07,
2896 "CR08", 0x08,
2897 "CR09", 0x09,
2898 "CR0A", 0x0A,
2899 "CR0B", 0x0B,
2900 "CR0C", 0x0C,
2901 "CR0D", 0x0D,
2902 "CR0E", 0x0E,
2903 "CR0F", 0x0F,
2904 "CR10", 0x10,
2905 "CR11", 0x11,
2906 "CR12", 0x12,
2907 "CR13", 0x13,
2908 "CR14", 0x14,
2909 "CR15", 0x15,
2910 "CR16", 0x16,
2911 "CR17", 0x17,
2912 "CR18", 0x18,
2913 "CR22", 0x22,
2914 "CR24", 0x24,
2915 "CR26", 0x26,
2916 "CR2D", 0x2D,
2917 "CR2E", 0x2E,
2918 "CR2F", 0x2F,
2919 "CR30", 0x30,
2920 "CR31", 0x31,
2921 "CR32", 0x32,
2922 "CR33", 0x33,
2923 "CR34", 0x34,
2924 "CR35", 0x35,
2925 "CR36", 0x36,
2926 "CR37", 0x37,
2927 "CR38", 0x38,
2928 "CR39", 0x39,
2929 "CR3A", 0x3A,
2930 "CR3B", 0x3B,
2931 "CR3C", 0x3C,
2932 "CR3D", 0x3D,
2933 "CR3E", 0x3E,
2934 "CR3F", 0x3F,
2935 NULL);
2937 dev_dbg(info->device, "\n");
2939 dev_dbg(info->device, "VGA SEQ register dump:\n");
2941 cirrusfb_dbg_print_regs(info, regbase, SEQ,
2942 "SR00", 0x00,
2943 "SR01", 0x01,
2944 "SR02", 0x02,
2945 "SR03", 0x03,
2946 "SR04", 0x04,
2947 "SR08", 0x08,
2948 "SR09", 0x09,
2949 "SR0A", 0x0A,
2950 "SR0B", 0x0B,
2951 "SR0D", 0x0D,
2952 "SR10", 0x10,
2953 "SR11", 0x11,
2954 "SR12", 0x12,
2955 "SR13", 0x13,
2956 "SR14", 0x14,
2957 "SR15", 0x15,
2958 "SR16", 0x16,
2959 "SR17", 0x17,
2960 "SR18", 0x18,
2961 "SR19", 0x19,
2962 "SR1A", 0x1A,
2963 "SR1B", 0x1B,
2964 "SR1C", 0x1C,
2965 "SR1D", 0x1D,
2966 "SR1E", 0x1E,
2967 "SR1F", 0x1F,
2968 NULL);
2970 dev_dbg(info->device, "\n");
2973 #endif /* CIRRUSFB_DEBUG */