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