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