1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37#define CIRRUSFB_VERSION "2.0-pre2"
38
39#include <linux/config.h>
40#include <linux/module.h>
41#include <linux/kernel.h>
42#include <linux/errno.h>
43#include <linux/string.h>
44#include <linux/mm.h>
45#include <linux/tty.h>
46#include <linux/slab.h>
47#include <linux/delay.h>
48#include <linux/fb.h>
49#include <linux/init.h>
50#include <linux/selection.h>
51#include <asm/pgtable.h>
52
53#ifdef CONFIG_ZORRO
54#include <linux/zorro.h>
55#endif
56#ifdef CONFIG_PCI
57#include <linux/pci.h>
58#endif
59#ifdef CONFIG_AMIGA
60#include <asm/amigahw.h>
61#endif
62#ifdef CONFIG_PPC_PREP
63#include <asm/processor.h>
64#define isPReP (_machine == _MACH_prep)
65#else
66#define isPReP 0
67#endif
68
69#include "video/vga.h"
70#include "video/cirrus.h"
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86#ifdef CIRRUSFB_DEBUG
87#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
88#else
89#define DPRINTK(fmt, args...)
90#endif
91
92
93#ifndef CIRRUSFB_NDEBUG
94#define assert(expr) \
95 if(!(expr)) { \
96 printk( "Assertion failed! %s,%s,%s,line=%d\n",\
97 #expr,__FILE__,__FUNCTION__,__LINE__); \
98 }
99#else
100#define assert(expr)
101#endif
102
103#ifdef TRUE
104#undef TRUE
105#endif
106#ifdef FALSE
107#undef FALSE
108#endif
109#define TRUE 1
110#define FALSE 0
111
112#define MB_ (1024*1024)
113#define KB_ (1024)
114
115#define MAX_NUM_BOARDS 7
116
117
118
119
120
121
122
123
124
125typedef enum {
126 BT_NONE = 0,
127 BT_SD64,
128 BT_PICCOLO,
129 BT_PICASSO,
130 BT_SPECTRUM,
131 BT_PICASSO4,
132 BT_ALPINE,
133 BT_GD5480,
134 BT_LAGUNA,
135} cirrusfb_board_t;
136
137
138
139
140
141
142
143
144
145
146
147static const struct cirrusfb_board_info_rec {
148 char *name;
149 long maxclock[5];
150
151 unsigned init_sr07 : 1;
152 unsigned init_sr1f : 1;
153 unsigned scrn_start_bit19 : 1;
154
155
156 unsigned char sr07;
157 unsigned char sr07_1bpp;
158 unsigned char sr07_1bpp_mux;
159 unsigned char sr07_8bpp;
160 unsigned char sr07_8bpp_mux;
161
162 unsigned char sr1f;
163} cirrusfb_board_info[] = {
164 [BT_SD64] = {
165 .name = "CL SD64",
166 .maxclock = {
167
168
169 140000, 140000, 140000, 140000, 140000,
170 },
171 .init_sr07 = TRUE,
172 .init_sr1f = TRUE,
173 .scrn_start_bit19 = TRUE,
174 .sr07 = 0xF0,
175 .sr07_1bpp = 0xF0,
176 .sr07_8bpp = 0xF1,
177 .sr1f = 0x20
178 },
179 [BT_PICCOLO] = {
180 .name = "CL Piccolo",
181 .maxclock = {
182
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_PICASSO] = {
194 .name = "CL Picasso",
195 .maxclock = {
196
197 90000, 90000, 90000, 90000, 90000
198 },
199 .init_sr07 = TRUE,
200 .init_sr1f = TRUE,
201 .scrn_start_bit19 = FALSE,
202 .sr07 = 0x20,
203 .sr07_1bpp = 0x20,
204 .sr07_8bpp = 0x21,
205 .sr1f = 0x22
206 },
207 [BT_SPECTRUM] = {
208 .name = "CL Spectrum",
209 .maxclock = {
210
211 90000, 90000, 90000, 90000, 90000
212 },
213 .init_sr07 = TRUE,
214 .init_sr1f = TRUE,
215 .scrn_start_bit19 = FALSE,
216 .sr07 = 0x80,
217 .sr07_1bpp = 0x80,
218 .sr07_8bpp = 0x81,
219 .sr1f = 0x22
220 },
221 [BT_PICASSO4] = {
222 .name = "CL Picasso4",
223 .maxclock = {
224 135100, 135100, 85500, 85500, 0
225 },
226 .init_sr07 = TRUE,
227 .init_sr1f = FALSE,
228 .scrn_start_bit19 = TRUE,
229 .sr07 = 0x20,
230 .sr07_1bpp = 0x20,
231 .sr07_8bpp = 0x21,
232 .sr1f = 0
233 },
234 [BT_ALPINE] = {
235 .name = "CL Alpine",
236 .maxclock = {
237
238 85500, 85500, 50000, 28500, 0
239 },
240 .init_sr07 = TRUE,
241 .init_sr1f = TRUE,
242 .scrn_start_bit19 = TRUE,
243 .sr07 = 0xA0,
244 .sr07_1bpp = 0xA1,
245 .sr07_1bpp_mux = 0xA7,
246 .sr07_8bpp = 0xA1,
247 .sr07_8bpp_mux = 0xA7,
248 .sr1f = 0x1C
249 },
250 [BT_GD5480] = {
251 .name = "CL GD5480",
252 .maxclock = {
253 135100, 200000, 200000, 135100, 135100
254 },
255 .init_sr07 = TRUE,
256 .init_sr1f = TRUE,
257 .scrn_start_bit19 = TRUE,
258 .sr07 = 0x10,
259 .sr07_1bpp = 0x11,
260 .sr07_8bpp = 0x11,
261 .sr1f = 0x1C
262 },
263 [BT_LAGUNA] = {
264 .name = "CL Laguna",
265 .maxclock = {
266
267 135100, 135100, 135100, 135100, 135100,
268 },
269 .init_sr07 = FALSE,
270 .init_sr1f = FALSE,
271 .scrn_start_bit19 = TRUE,
272 }
273};
274
275
276#ifdef CONFIG_PCI
277#define CHIP(id, btype) \
278 { PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_##id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
279
280static struct pci_device_id cirrusfb_pci_table[] = {
281 CHIP( CIRRUS_5436, BT_ALPINE ),
282 CHIP( CIRRUS_5434_8, BT_ALPINE ),
283 CHIP( CIRRUS_5434_4, BT_ALPINE ),
284 CHIP( CIRRUS_5430, BT_ALPINE ),
285 CHIP( CIRRUS_7543, BT_ALPINE ),
286 CHIP( CIRRUS_7548, BT_ALPINE ),
287 CHIP( CIRRUS_5480, BT_GD5480 ),
288 CHIP( CIRRUS_5446, BT_PICASSO4 ),
289 CHIP( CIRRUS_5462, BT_LAGUNA ),
290 CHIP( CIRRUS_5464, BT_LAGUNA ),
291 CHIP( CIRRUS_5465, BT_LAGUNA ),
292 { 0, }
293};
294MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
295#undef CHIP
296#endif
297
298
299#ifdef CONFIG_ZORRO
300static const struct zorro_device_id cirrusfb_zorro_table[] = {
301 {
302 .id = ZORRO_PROD_HELFRICH_SD64_RAM,
303 .driver_data = BT_SD64,
304 }, {
305 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
306 .driver_data = BT_PICCOLO,
307 }, {
308 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
309 .driver_data = BT_PICASSO,
310 }, {
311 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
312 .driver_data = BT_SPECTRUM,
313 }, {
314 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
315 .driver_data = BT_PICASSO4,
316 },
317 { 0 }
318};
319
320static const struct {
321 zorro_id id2;
322 unsigned long size;
323} cirrusfb_zorro_table2[] = {
324 [BT_SD64] = {
325 .id2 = ZORRO_PROD_HELFRICH_SD64_REG,
326 .size = 0x400000
327 },
328 [BT_PICCOLO] = {
329 .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG,
330 .size = 0x200000
331 },
332 [BT_PICASSO] = {
333 .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
334 .size = 0x200000
335 },
336 [BT_SPECTRUM] = {
337 .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
338 .size = 0x200000
339 },
340 [BT_PICASSO4] = {
341 .id2 = 0,
342 .size = 0x400000
343 }
344};
345#endif
346
347
348struct cirrusfb_regs {
349 __u32 line_length;
350 __u32 visual;
351 __u32 type;
352
353 long freq;
354 long nom;
355 long den;
356 long div;
357 long multiplexing;
358 long mclk;
359 long divMCLK;
360
361 long HorizRes;
362 long HorizTotal;
363 long HorizDispEnd;
364 long HorizBlankStart;
365 long HorizBlankEnd;
366 long HorizSyncStart;
367 long HorizSyncEnd;
368
369 long VertRes;
370 long VertTotal;
371 long VertDispEnd;
372 long VertSyncStart;
373 long VertSyncEnd;
374 long VertBlankStart;
375 long VertBlankEnd;
376};
377
378
379
380#ifdef CIRRUSFB_DEBUG
381typedef enum {
382 CRT,
383 SEQ
384} cirrusfb_dbg_reg_class_t;
385#endif
386
387
388
389
390
391struct cirrusfb_info {
392 struct fb_info *info;
393
394 u8 __iomem *fbmem;
395 u8 __iomem *regbase;
396 u8 __iomem *mem;
397 unsigned long size;
398 cirrusfb_board_t btype;
399 unsigned char SFR;
400
401 unsigned long fbmem_phys;
402 unsigned long fbregs_phys;
403
404 struct cirrusfb_regs currentmode;
405 int blank_mode;
406
407 u32 pseudo_palette[17];
408 struct { u8 red, green, blue, pad; } palette[256];
409
410#ifdef CONFIG_ZORRO
411 struct zorro_dev *zdev;
412#endif
413#ifdef CONFIG_PCI
414 struct pci_dev *pdev;
415#endif
416 void (*unmap)(struct cirrusfb_info *cinfo);
417};
418
419
420static unsigned cirrusfb_def_mode = 1;
421static int noaccel = 0;
422
423
424
425
426
427static const struct {
428 const char *name;
429 struct fb_var_screeninfo var;
430} cirrusfb_predefined[] = {
431 {
432
433 .name = "Autodetect",
434 }, {
435
436 .name = "640x480",
437 .var = {
438 .xres = 640,
439 .yres = 480,
440 .xres_virtual = 640,
441 .yres_virtual = 480,
442 .bits_per_pixel = 8,
443 .red = { .length = 8 },
444 .green = { .length = 8 },
445 .blue = { .length = 8 },
446 .width = -1,
447 .height = -1,
448 .pixclock = 40000,
449 .left_margin = 48,
450 .right_margin = 16,
451 .upper_margin = 32,
452 .lower_margin = 8,
453 .hsync_len = 96,
454 .vsync_len = 4,
455 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
456 .vmode = FB_VMODE_NONINTERLACED
457 }
458 }, {
459
460 .name = "800x600",
461 .var = {
462 .xres = 800,
463 .yres = 600,
464 .xres_virtual = 800,
465 .yres_virtual = 600,
466 .bits_per_pixel = 8,
467 .red = { .length = 8 },
468 .green = { .length = 8 },
469 .blue = { .length = 8 },
470 .width = -1,
471 .height = -1,
472 .pixclock = 20000,
473 .left_margin = 128,
474 .right_margin = 16,
475 .upper_margin = 24,
476 .lower_margin = 2,
477 .hsync_len = 96,
478 .vsync_len = 6,
479 .vmode = FB_VMODE_NONINTERLACED
480 }
481 }, {
482
483
484
485
486
487 .name = "1024x768",
488 .var = {
489 .xres = 1024,
490 .yres = 768,
491 .xres_virtual = 1024,
492 .yres_virtual = 768,
493 .bits_per_pixel = 8,
494 .red = { .length = 8 },
495 .green = { .length = 8 },
496 .blue = { .length = 8 },
497 .width = -1,
498 .height = -1,
499 .pixclock = 12500,
500 .left_margin = 144,
501 .right_margin = 32,
502 .upper_margin = 30,
503 .lower_margin = 2,
504 .hsync_len = 192,
505 .vsync_len = 6,
506 .vmode = FB_VMODE_NONINTERLACED
507 }
508 }
509};
510
511#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined)
512
513
514
515
516
517
518int cirrusfb_init (void);
519int cirrusfb_setup (char *options);
520
521int cirrusfb_open (struct fb_info *info, int user);
522int cirrusfb_release (struct fb_info *info, int user);
523int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
524 unsigned blue, unsigned transp,
525 struct fb_info *info);
526int cirrusfb_check_var (struct fb_var_screeninfo *var,
527 struct fb_info *info);
528int cirrusfb_set_par (struct fb_info *info);
529int cirrusfb_pan_display (struct fb_var_screeninfo *var,
530 struct fb_info *info);
531int cirrusfb_blank (int blank_mode, struct fb_info *info);
532void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region);
533void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
534void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image);
535
536
537static struct fb_ops cirrusfb_ops = {
538 .owner = THIS_MODULE,
539 .fb_open = cirrusfb_open,
540 .fb_release = cirrusfb_release,
541 .fb_setcolreg = cirrusfb_setcolreg,
542 .fb_check_var = cirrusfb_check_var,
543 .fb_set_par = cirrusfb_set_par,
544 .fb_pan_display = cirrusfb_pan_display,
545 .fb_blank = cirrusfb_blank,
546 .fb_fillrect = cirrusfb_fillrect,
547 .fb_copyarea = cirrusfb_copyarea,
548 .fb_imageblit = cirrusfb_imageblit,
549 .fb_cursor = soft_cursor,
550};
551
552
553static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
554 struct cirrusfb_regs *regs,
555 const struct fb_info *info);
556
557static void init_vgachip (struct cirrusfb_info *cinfo);
558static void switch_monitor (struct cirrusfb_info *cinfo, int on);
559static void WGen (const struct cirrusfb_info *cinfo,
560 int regnum, unsigned char val);
561static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum);
562static void AttrOn (const struct cirrusfb_info *cinfo);
563static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val);
564static void WSFR (struct cirrusfb_info *cinfo, unsigned char val);
565static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val);
566static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
567 unsigned char green,
568 unsigned char blue);
569#if 0
570static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
571 unsigned char *green,
572 unsigned char *blue);
573#endif
574static void cirrusfb_WaitBLT (u8 __iomem *regbase);
575static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
576 u_short curx, u_short cury,
577 u_short destx, u_short desty,
578 u_short width, u_short height,
579 u_short line_length);
580static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
581 u_short x, u_short y,
582 u_short width, u_short height,
583 u_char color, u_short line_length);
584
585static void bestclock (long freq, long *best,
586 long *nom, long *den,
587 long *div, long maxfreq);
588
589#ifdef CIRRUSFB_DEBUG
590static void cirrusfb_dump (void);
591static void cirrusfb_dbg_reg_dump (caddr_t regbase);
592static void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...);
593static void cirrusfb_dbg_print_byte (const char *name, unsigned char val);
594#endif
595
596
597
598
599
600static int opencount = 0;
601
602
603int cirrusfb_open (struct fb_info *info, int user)
604{
605 if (opencount++ == 0)
606 switch_monitor (info->par, 1);
607 return 0;
608}
609
610
611int cirrusfb_release (struct fb_info *info, int user)
612{
613 if (--opencount == 0)
614 switch_monitor (info->par, 0);
615 return 0;
616}
617
618
619
620
621
622
623static long cirrusfb_get_mclk (long freq, int bpp, long *div)
624{
625 long mclk;
626
627 assert (div != NULL);
628
629
630
631
632
633 mclk = ((bpp / 8) * freq * 2) / 4;
634 mclk = (mclk * 12) / 10;
635 if (mclk < 50000)
636 mclk = 50000;
637 DPRINTK ("Use MCLK of %ld kHz\n", mclk);
638
639
640 mclk = ((mclk * 16) / 14318);
641 mclk = (mclk + 1) / 2;
642 DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk);
643
644
645
646 switch (freq) {
647 case 24751 ... 25249:
648 *div = 2;
649 DPRINTK ("Using VCLK = MCLK/2\n");
650 break;
651 case 49501 ... 50499:
652 *div = 1;
653 DPRINTK ("Using VCLK = MCLK\n");
654 break;
655 default:
656 *div = 0;
657 break;
658 }
659
660 return mclk;
661}
662
663int cirrusfb_check_var(struct fb_var_screeninfo *var,
664 struct fb_info *info)
665{
666 struct cirrusfb_info *cinfo = info->par;
667 int nom, den;
668 int yres, i;
669 static struct { int xres, yres; } modes[] =
670 { { 1600, 1280 },
671 { 1280, 1024 },
672 { 1024, 768 },
673 { 800, 600 },
674 { 640, 480 },
675 { -1, -1 } };
676
677 switch (var->bits_per_pixel) {
678 case 0 ... 1:
679 var->bits_per_pixel = 1;
680 nom = 4;
681 den = 8;
682 break;
683 case 2 ... 8:
684 var->bits_per_pixel = 8;
685 nom = 1;
686 den = 1;
687 break;
688 case 9 ... 16:
689 var->bits_per_pixel = 16;
690 nom = 2;
691 den = 1;
692 break;
693 case 17 ... 24:
694 var->bits_per_pixel = 24;
695 nom = 3;
696 den = 1;
697 break;
698 case 25 ... 32:
699 var->bits_per_pixel = 32;
700 nom = 4;
701 den = 1;
702 break;
703 default:
704 printk ("cirrusfb: mode %dx%dx%d rejected...color depth not supported.\n",
705 var->xres, var->yres, var->bits_per_pixel);
706 DPRINTK ("EXIT - EINVAL error\n");
707 return -EINVAL;
708 }
709
710 if (var->xres * nom / den * var->yres > cinfo->size) {
711 printk ("cirrusfb: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
712 var->xres, var->yres, var->bits_per_pixel);
713 DPRINTK ("EXIT - EINVAL error\n");
714 return -EINVAL;
715 }
716
717
718 if (var->xres_virtual == -1 &&
719 var->yres_virtual == -1) {
720 printk ("cirrusfb: using maximum available virtual resolution\n");
721 for (i = 0; modes[i].xres != -1; i++) {
722 if (modes[i].xres * nom / den * modes[i].yres < cinfo->size / 2)
723 break;
724 }
725 if (modes[i].xres == -1) {
726 printk ("cirrusfb: could not find a virtual resolution that fits into video memory!!\n");
727 DPRINTK ("EXIT - EINVAL error\n");
728 return -EINVAL;
729 }
730 var->xres_virtual = modes[i].xres;
731 var->yres_virtual = modes[i].yres;
732
733 printk ("cirrusfb: virtual resolution set to maximum of %dx%d\n",
734 var->xres_virtual, var->yres_virtual);
735 }
736
737 if (var->xres_virtual < var->xres)
738 var->xres_virtual = var->xres;
739 if (var->yres_virtual < var->yres)
740 var->yres_virtual = var->yres;
741
742 if (var->xoffset < 0)
743 var->xoffset = 0;
744 if (var->yoffset < 0)
745 var->yoffset = 0;
746
747
748 if (var->xoffset > var->xres_virtual - var->xres)
749 var->xoffset = var->xres_virtual - var->xres - 1;
750 if (var->yoffset > var->yres_virtual - var->yres)
751 var->yoffset = var->yres_virtual - var->yres - 1;
752
753 switch (var->bits_per_pixel) {
754 case 1:
755 var->red.offset = 0;
756 var->red.length = 1;
757 var->green.offset = 0;
758 var->green.length = 1;
759 var->blue.offset = 0;
760 var->blue.length = 1;
761 break;
762
763 case 8:
764 var->red.offset = 0;
765 var->red.length = 6;
766 var->green.offset = 0;
767 var->green.length = 6;
768 var->blue.offset = 0;
769 var->blue.length = 6;
770 break;
771
772 case 16:
773 if(isPReP) {
774 var->red.offset = 2;
775 var->green.offset = -3;
776 var->blue.offset = 8;
777 } else {
778 var->red.offset = 10;
779 var->green.offset = 5;
780 var->blue.offset = 0;
781 }
782 var->red.length = 5;
783 var->green.length = 5;
784 var->blue.length = 5;
785 break;
786
787 case 24:
788 if(isPReP) {
789 var->red.offset = 8;
790 var->green.offset = 16;
791 var->blue.offset = 24;
792 } else {
793 var->red.offset = 16;
794 var->green.offset = 8;
795 var->blue.offset = 0;
796 }
797 var->red.length = 8;
798 var->green.length = 8;
799 var->blue.length = 8;
800 break;
801
802 case 32:
803 if(isPReP) {
804 var->red.offset = 8;
805 var->green.offset = 16;
806 var->blue.offset = 24;
807 } else {
808 var->red.offset = 16;
809 var->green.offset = 8;
810 var->blue.offset = 0;
811 }
812 var->red.length = 8;
813 var->green.length = 8;
814 var->blue.length = 8;
815 break;
816
817 default:
818 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
819 assert (FALSE);
820
821 break;
822 }
823
824 var->red.msb_right =
825 var->green.msb_right =
826 var->blue.msb_right =
827 var->transp.offset =
828 var->transp.length =
829 var->transp.msb_right = 0;
830
831 yres = var->yres;
832 if (var->vmode & FB_VMODE_DOUBLE)
833 yres *= 2;
834 else if (var->vmode & FB_VMODE_INTERLACED)
835 yres = (yres + 1) / 2;
836
837 if (yres >= 1280) {
838 printk (KERN_WARNING "cirrusfb: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n");
839 DPRINTK ("EXIT - EINVAL error\n");
840 return -EINVAL;
841 }
842
843 return 0;
844}
845
846static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
847 struct cirrusfb_regs *regs,
848 const struct fb_info *info)
849{
850 long freq;
851 long maxclock;
852 int maxclockidx = 0;
853 struct cirrusfb_info *cinfo = info->par;
854 int xres, hfront, hsync, hback;
855 int yres, vfront, vsync, vback;
856
857 switch(var->bits_per_pixel) {
858 case 1:
859 regs->line_length = var->xres_virtual / 8;
860 regs->visual = FB_VISUAL_MONO10;
861 maxclockidx = 0;
862 break;
863
864 case 8:
865 regs->line_length = var->xres_virtual;
866 regs->visual = FB_VISUAL_PSEUDOCOLOR;
867 maxclockidx = 1;
868 break;
869
870 case 16:
871 regs->line_length = var->xres_virtual * 2;
872 regs->visual = FB_VISUAL_DIRECTCOLOR;
873 maxclockidx = 2;
874 break;
875
876 case 24:
877 regs->line_length = var->xres_virtual * 3;
878 regs->visual = FB_VISUAL_DIRECTCOLOR;
879 maxclockidx = 3;
880 break;
881
882 case 32:
883 regs->line_length = var->xres_virtual * 4;
884 regs->visual = FB_VISUAL_DIRECTCOLOR;
885 maxclockidx = 4;
886 break;
887
888 default:
889 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
890 assert (FALSE);
891
892 break;
893 }
894
895 regs->type = FB_TYPE_PACKED_PIXELS;
896
897
898 freq = 1000000000 / var->pixclock;
899
900 DPRINTK ("desired pixclock: %ld kHz\n", freq);
901
902 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
903 regs->multiplexing = 0;
904
905
906
907 if (freq > maxclock) {
908 switch (cinfo->btype) {
909 case BT_ALPINE:
910 case BT_GD5480:
911 regs->multiplexing = 1;
912 break;
913
914 default:
915 printk (KERN_WARNING "cirrusfb: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock);
916 DPRINTK ("EXIT - return -EINVAL\n");
917 return -EINVAL;
918 }
919 }
920#if 0
921
922
923 switch (var->bits_per_pixel) {
924 case 16:
925 case 32:
926 if (regs->HorizRes <= 800)
927 freq /= 2;
928 break;
929 }
930#endif
931
932 bestclock (freq, ®s->freq, ®s->nom, ®s->den, ®s->div,
933 maxclock);
934 regs->mclk = cirrusfb_get_mclk (freq, var->bits_per_pixel, ®s->divMCLK);
935
936 xres = var->xres;
937 hfront = var->right_margin;
938 hsync = var->hsync_len;
939 hback = var->left_margin;
940
941 yres = var->yres;
942 vfront = var->lower_margin;
943 vsync = var->vsync_len;
944 vback = var->upper_margin;
945
946 if (var->vmode & FB_VMODE_DOUBLE) {
947 yres *= 2;
948 vfront *= 2;
949 vsync *= 2;
950 vback *= 2;
951 } else if (var->vmode & FB_VMODE_INTERLACED) {
952 yres = (yres + 1) / 2;
953 vfront = (vfront + 1) / 2;
954 vsync = (vsync + 1) / 2;
955 vback = (vback + 1) / 2;
956 }
957 regs->HorizRes = xres;
958 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
959 regs->HorizDispEnd = xres / 8 - 1;
960 regs->HorizBlankStart = xres / 8;
961 regs->HorizBlankEnd = regs->HorizTotal + 5;
962 regs->HorizSyncStart = (xres + hfront) / 8 + 1;
963 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
964
965 regs->VertRes = yres;
966 regs->VertTotal = yres + vfront + vsync + vback - 2;
967 regs->VertDispEnd = yres - 1;
968 regs->VertBlankStart = yres;
969 regs->VertBlankEnd = regs->VertTotal;
970 regs->VertSyncStart = yres + vfront - 1;
971 regs->VertSyncEnd = yres + vfront + vsync - 1;
972
973 if (regs->VertRes >= 1024) {
974 regs->VertTotal /= 2;
975 regs->VertSyncStart /= 2;
976 regs->VertSyncEnd /= 2;
977 regs->VertDispEnd /= 2;
978 }
979 if (regs->multiplexing) {
980 regs->HorizTotal /= 2;
981 regs->HorizSyncStart /= 2;
982 regs->HorizSyncEnd /= 2;
983 regs->HorizDispEnd /= 2;
984 }
985
986 return 0;
987}
988
989
990static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int div)
991{
992 assert (cinfo != NULL);
993
994 if (div == 2) {
995
996 unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E);
997 vga_wseq (cinfo->regbase, CL_SEQR1E, old | 0x1);
998 vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
999 } else if (div == 1) {
1000
1001 unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E);
1002 vga_wseq (cinfo->regbase, CL_SEQR1E, old & ~0x1);
1003 vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
1004 } else {
1005 vga_wseq (cinfo->regbase, CL_SEQR1F, val & 0x3f);
1006 }
1007}
1008
1009
1010
1011
1012
1013
1014static int cirrusfb_set_par_foo (struct fb_info *info)
1015{
1016 struct cirrusfb_info *cinfo = info->par;
1017 struct fb_var_screeninfo *var = &info->var;
1018 struct cirrusfb_regs regs;
1019 u8 __iomem *regbase = cinfo->regbase;
1020 unsigned char tmp;
1021 int offset = 0, err;
1022 const struct cirrusfb_board_info_rec *bi;
1023
1024 DPRINTK ("ENTER\n");
1025 DPRINTK ("Requested mode: %dx%dx%d\n",
1026 var->xres, var->yres, var->bits_per_pixel);
1027 DPRINTK ("pixclock: %d\n", var->pixclock);
1028
1029 init_vgachip (cinfo);
1030
1031 err = cirrusfb_decode_var(var, ®s, info);
1032 if(err) {
1033
1034 DPRINTK("mode change aborted. invalid var.\n");
1035 return -EINVAL;
1036 }
1037
1038 bi = &cirrusfb_board_info[cinfo->btype];
1039
1040
1041
1042 vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20);
1043
1044
1045 DPRINTK ("CRT0: %ld\n", regs.HorizTotal);
1046 vga_wcrt (regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
1047
1048 DPRINTK ("CRT1: %ld\n", regs.HorizDispEnd);
1049 vga_wcrt (regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
1050
1051 DPRINTK ("CRT2: %ld\n", regs.HorizBlankStart);
1052 vga_wcrt (regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
1053
1054 DPRINTK ("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
1055 vga_wcrt (regbase, VGA_CRTC_H_BLANK_END, 128 + (regs.HorizBlankEnd % 32));
1056
1057 DPRINTK ("CRT4: %ld\n", regs.HorizSyncStart);
1058 vga_wcrt (regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
1059
1060 tmp = regs.HorizSyncEnd % 32;
1061 if (regs.HorizBlankEnd & 32)
1062 tmp += 128;
1063 DPRINTK ("CRT5: %d\n", tmp);
1064 vga_wcrt (regbase, VGA_CRTC_H_SYNC_END, tmp);
1065
1066 DPRINTK ("CRT6: %ld\n", regs.VertTotal & 0xff);
1067 vga_wcrt (regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
1068
1069 tmp = 16;
1070 if (regs.VertTotal & 256)
1071 tmp |= 1;
1072 if (regs.VertDispEnd & 256)
1073 tmp |= 2;
1074 if (regs.VertSyncStart & 256)
1075 tmp |= 4;
1076 if (regs.VertBlankStart & 256)
1077 tmp |= 8;
1078 if (regs.VertTotal & 512)
1079 tmp |= 32;
1080 if (regs.VertDispEnd & 512)
1081 tmp |= 64;
1082 if (regs.VertSyncStart & 512)
1083 tmp |= 128;
1084 DPRINTK ("CRT7: %d\n", tmp);
1085 vga_wcrt (regbase, VGA_CRTC_OVERFLOW, tmp);
1086
1087 tmp = 0x40;
1088 if (regs.VertBlankStart & 512)
1089 tmp |= 0x20;
1090 if (var->vmode & FB_VMODE_DOUBLE)
1091 tmp |= 0x80;
1092 DPRINTK ("CRT9: %d\n", tmp);
1093 vga_wcrt (regbase, VGA_CRTC_MAX_SCAN, tmp);
1094
1095 DPRINTK ("CRT10: %ld\n", regs.VertSyncStart & 0xff);
1096 vga_wcrt (regbase, VGA_CRTC_V_SYNC_START, (regs.VertSyncStart & 0xff));
1097
1098 DPRINTK ("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
1099 vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, (regs.VertSyncEnd % 16 + 64 + 32));
1100
1101 DPRINTK ("CRT12: %ld\n", regs.VertDispEnd & 0xff);
1102 vga_wcrt (regbase, VGA_CRTC_V_DISP_END, (regs.VertDispEnd & 0xff));
1103
1104 DPRINTK ("CRT15: %ld\n", regs.VertBlankStart & 0xff);
1105 vga_wcrt (regbase, VGA_CRTC_V_BLANK_START, (regs.VertBlankStart & 0xff));
1106
1107 DPRINTK ("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
1108 vga_wcrt (regbase, VGA_CRTC_V_BLANK_END, (regs.VertBlankEnd & 0xff));
1109
1110 DPRINTK ("CRT18: 0xff\n");
1111 vga_wcrt (regbase, VGA_CRTC_LINE_COMPARE, 0xff);
1112
1113 tmp = 0;
1114 if (var->vmode & FB_VMODE_INTERLACED)
1115 tmp |= 1;
1116 if (regs.HorizBlankEnd & 64)
1117 tmp |= 16;
1118 if (regs.HorizBlankEnd & 128)
1119 tmp |= 32;
1120 if (regs.VertBlankEnd & 256)
1121 tmp |= 64;
1122 if (regs.VertBlankEnd & 512)
1123 tmp |= 128;
1124
1125 DPRINTK ("CRT1a: %d\n", tmp);
1126 vga_wcrt (regbase, CL_CRT1A, tmp);
1127
1128
1129
1130
1131
1132
1133 vga_wseq (regbase, CL_SEQRB, regs.nom);
1134 tmp = regs.den << 1;
1135 if (regs.div != 0)
1136 tmp |= 1;
1137
1138 if ((cinfo->btype == BT_SD64) ||
1139 (cinfo->btype == BT_ALPINE) ||
1140 (cinfo->btype == BT_GD5480))
1141 tmp |= 0x80;
1142
1143 DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp);
1144 vga_wseq (regbase, CL_SEQR1B, tmp);
1145
1146 if (regs.VertRes >= 1024)
1147
1148 vga_wcrt (regbase, VGA_CRTC_MODE, 0xc7);
1149 else
1150
1151
1152 vga_wcrt (regbase, VGA_CRTC_MODE, 0xc3);
1153
1154
1155
1156
1157
1158 if (var->vmode & FB_VMODE_INTERLACED)
1159 vga_wcrt (regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
1160 else
1161 vga_wcrt (regbase, VGA_CRTC_REGS, 0x00);
1162
1163 vga_wseq (regbase, VGA_SEQ_CHARACTER_MAP, 0);
1164
1165
1166 tmp = 0x03;
1167 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
1168 tmp |= 0x40;
1169 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
1170 tmp |= 0x80;
1171 WGen (cinfo, VGA_MIS_W, tmp);
1172
1173 vga_wcrt (regbase, VGA_CRTC_PRESET_ROW, 0);
1174 vga_wcrt (regbase, VGA_CRTC_CURSOR_START, 0);
1175 vga_wcrt (regbase, VGA_CRTC_CURSOR_END, 31);
1176
1177
1178
1179
1180
1181
1182
1183
1184 if (var->bits_per_pixel == 1) {
1185 DPRINTK ("cirrusfb: preparing for 1 bit deep display\n");
1186 vga_wgfx (regbase, VGA_GFX_MODE, 0);
1187
1188
1189 switch (cinfo->btype) {
1190 case BT_SD64:
1191 case BT_PICCOLO:
1192 case BT_PICASSO:
1193 case BT_SPECTRUM:
1194 case BT_PICASSO4:
1195 case BT_ALPINE:
1196 case BT_GD5480:
1197 DPRINTK (" (for GD54xx)\n");
1198 vga_wseq (regbase, CL_SEQR7,
1199 regs.multiplexing ?
1200 bi->sr07_1bpp_mux : bi->sr07_1bpp);
1201 break;
1202
1203 case BT_LAGUNA:
1204 DPRINTK (" (for GD546x)\n");
1205 vga_wseq (regbase, CL_SEQR7,
1206 vga_rseq (regbase, CL_SEQR7) & ~0x01);
1207 break;
1208
1209 default:
1210 printk (KERN_WARNING "cirrusfb: unknown Board\n");
1211 break;
1212 }
1213
1214
1215 switch (cinfo->btype) {
1216 case BT_SD64:
1217
1218 DPRINTK ("(for SD64)\n");
1219 vga_wseq (regbase, CL_SEQR1F, 0x1a);
1220 break;
1221
1222 case BT_PICCOLO:
1223 DPRINTK ("(for Piccolo)\n");
1224
1225 vga_wseq (regbase, CL_SEQR1F, 0x22);
1226 vga_wseq (regbase, CL_SEQRF, 0xb0);
1227 break;
1228
1229 case BT_PICASSO:
1230 DPRINTK ("(for Picasso)\n");
1231 vga_wseq (regbase, CL_SEQR1F, 0x22);
1232 vga_wseq (regbase, CL_SEQRF, 0xd0);
1233 break;
1234
1235 case BT_SPECTRUM:
1236 DPRINTK ("(for Spectrum)\n");
1237
1238 vga_wseq (regbase, CL_SEQR1F, 0x22);
1239 vga_wseq (regbase, CL_SEQRF, 0xb0);
1240 break;
1241
1242 case BT_PICASSO4:
1243 case BT_ALPINE:
1244 case BT_GD5480:
1245 case BT_LAGUNA:
1246 DPRINTK (" (for GD54xx)\n");
1247
1248 break;
1249
1250 default:
1251 printk (KERN_WARNING "cirrusfb: unknown Board\n");
1252 break;
1253 }
1254
1255 WGen (cinfo, VGA_PEL_MSK, 0x01);
1256 if (regs.multiplexing)
1257 WHDR (cinfo, 0x4a);
1258 else
1259 WHDR (cinfo, 0);
1260 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1261 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1262 offset = var->xres_virtual / 16;
1263 }
1264
1265
1266
1267
1268
1269
1270
1271 else if (var->bits_per_pixel == 8) {
1272 DPRINTK ("cirrusfb: preparing for 8 bit deep display\n");
1273 switch (cinfo->btype) {
1274 case BT_SD64:
1275 case BT_PICCOLO:
1276 case BT_PICASSO:
1277 case BT_SPECTRUM:
1278 case BT_PICASSO4:
1279 case BT_ALPINE:
1280 case BT_GD5480:
1281 DPRINTK (" (for GD54xx)\n");
1282 vga_wseq (regbase, CL_SEQR7,
1283 regs.multiplexing ?
1284 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1285 break;
1286
1287 case BT_LAGUNA:
1288 DPRINTK (" (for GD546x)\n");
1289 vga_wseq (regbase, CL_SEQR7,
1290 vga_rseq (regbase, CL_SEQR7) | 0x01);
1291 break;
1292
1293 default:
1294 printk (KERN_WARNING "cirrusfb: unknown Board\n");
1295 break;
1296 }
1297
1298 switch (cinfo->btype) {
1299 case BT_SD64:
1300 vga_wseq (regbase, CL_SEQR1F, 0x1d);
1301 break;
1302
1303 case BT_PICCOLO:
1304 vga_wseq (regbase, CL_SEQR1F, 0x22);
1305 vga_wseq (regbase, CL_SEQRF, 0xb0);
1306 break;
1307
1308 case BT_PICASSO:
1309 vga_wseq (regbase, CL_SEQR1F, 0x22);
1310 vga_wseq (regbase, CL_SEQRF, 0xb0);
1311 break;
1312
1313 case BT_SPECTRUM:
1314 vga_wseq (regbase, CL_SEQR1F, 0x22);
1315 vga_wseq (regbase, CL_SEQRF, 0xb0);
1316 break;
1317
1318 case BT_PICASSO4:
1319#ifdef CONFIG_ZORRO
1320 vga_wseq (regbase, CL_SEQRF, 0xb8);
1321#endif
1322
1323 break;
1324
1325 case BT_ALPINE:
1326 DPRINTK (" (for GD543x)\n");
1327 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK);
1328
1329 break;
1330
1331 case BT_GD5480:
1332 case BT_LAGUNA:
1333 DPRINTK (" (for GD54xx)\n");
1334
1335 break;
1336
1337 default:
1338 printk (KERN_WARNING "cirrusfb: unknown Board\n");
1339 break;
1340 }
1341
1342 vga_wgfx (regbase, VGA_GFX_MODE, 64);
1343 WGen (cinfo, VGA_PEL_MSK, 0xff);
1344 if (regs.multiplexing)
1345 WHDR (cinfo, 0x4a);
1346 else
1347 WHDR (cinfo, 0);
1348 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1349 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1350 offset = var->xres_virtual / 8;
1351 }
1352
1353
1354
1355
1356
1357
1358
1359 else if (var->bits_per_pixel == 16) {
1360 DPRINTK ("cirrusfb: preparing for 16 bit deep display\n");
1361 switch (cinfo->btype) {
1362 case BT_SD64:
1363 vga_wseq (regbase, CL_SEQR7, 0xf7);
1364 vga_wseq (regbase, CL_SEQR1F, 0x1e);
1365 break;
1366
1367 case BT_PICCOLO:
1368 vga_wseq (regbase, CL_SEQR7, 0x87);
1369 vga_wseq (regbase, CL_SEQRF, 0xb0);
1370 vga_wseq (regbase, CL_SEQR1F, 0x22);
1371 break;
1372
1373 case BT_PICASSO:
1374 vga_wseq (regbase, CL_SEQR7, 0x27);
1375 vga_wseq (regbase, CL_SEQRF, 0xb0);
1376 vga_wseq (regbase, CL_SEQR1F, 0x22);
1377 break;
1378
1379 case BT_SPECTRUM:
1380 vga_wseq (regbase, CL_SEQR7, 0x87);
1381 vga_wseq (regbase, CL_SEQRF, 0xb0);
1382 vga_wseq (regbase, CL_SEQR1F, 0x22);
1383 break;
1384
1385 case BT_PICASSO4:
1386 vga_wseq (regbase, CL_SEQR7, 0x27);
1387
1388 break;
1389
1390 case BT_ALPINE:
1391 DPRINTK (" (for GD543x)\n");
1392 if (regs.HorizRes >= 1024)
1393 vga_wseq (regbase, CL_SEQR7, 0xa7);
1394 else
1395 vga_wseq (regbase, CL_SEQR7, 0xa3);
1396 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK);
1397 break;
1398
1399 case BT_GD5480:
1400 DPRINTK (" (for GD5480)\n");
1401 vga_wseq (regbase, CL_SEQR7, 0x17);
1402
1403 break;
1404
1405 case BT_LAGUNA:
1406 DPRINTK (" (for GD546x)\n");
1407 vga_wseq (regbase, CL_SEQR7,
1408 vga_rseq (regbase, CL_SEQR7) & ~0x01);
1409 break;
1410
1411 default:
1412 printk (KERN_WARNING "CIRRUSFB: unknown Board\n");
1413 break;
1414 }
1415
1416 vga_wgfx (regbase, VGA_GFX_MODE, 64);
1417 WGen (cinfo, VGA_PEL_MSK, 0xff);
1418#ifdef CONFIG_PCI
1419 WHDR (cinfo, 0xc0);
1420#elif defined(CONFIG_ZORRO)
1421
1422 WHDR (cinfo, 0xa0);
1423#endif
1424 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1425 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1426 offset = var->xres_virtual / 4;
1427 }
1428
1429
1430
1431
1432
1433
1434
1435 else if (var->bits_per_pixel == 32) {
1436 DPRINTK ("cirrusfb: preparing for 24/32 bit deep display\n");
1437 switch (cinfo->btype) {
1438 case BT_SD64:
1439 vga_wseq (regbase, CL_SEQR7, 0xf9);
1440 vga_wseq (regbase, CL_SEQR1F, 0x1e);
1441 break;
1442
1443 case BT_PICCOLO:
1444 vga_wseq (regbase, CL_SEQR7, 0x85);
1445 vga_wseq (regbase, CL_SEQRF, 0xb0);
1446 vga_wseq (regbase, CL_SEQR1F, 0x22);
1447 break;
1448
1449 case BT_PICASSO:
1450 vga_wseq (regbase, CL_SEQR7, 0x25);
1451 vga_wseq (regbase, CL_SEQRF, 0xb0);
1452 vga_wseq (regbase, CL_SEQR1F, 0x22);
1453 break;
1454
1455 case BT_SPECTRUM:
1456 vga_wseq (regbase, CL_SEQR7, 0x85);
1457 vga_wseq (regbase, CL_SEQRF, 0xb0);
1458 vga_wseq (regbase, CL_SEQR1F, 0x22);
1459 break;
1460
1461 case BT_PICASSO4:
1462 vga_wseq (regbase, CL_SEQR7, 0x25);
1463
1464 break;
1465
1466 case BT_ALPINE:
1467 DPRINTK (" (for GD543x)\n");
1468 vga_wseq (regbase, CL_SEQR7, 0xa9);
1469 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK);
1470 break;
1471
1472 case BT_GD5480:
1473 DPRINTK (" (for GD5480)\n");
1474 vga_wseq (regbase, CL_SEQR7, 0x19);
1475
1476 break;
1477
1478 case BT_LAGUNA:
1479 DPRINTK (" (for GD546x)\n");
1480 vga_wseq (regbase, CL_SEQR7,
1481 vga_rseq (regbase, CL_SEQR7) & ~0x01);
1482 break;
1483
1484 default:
1485 printk (KERN_WARNING "cirrusfb: unknown Board\n");
1486 break;
1487 }
1488
1489 vga_wgfx (regbase, VGA_GFX_MODE, 64);
1490 WGen (cinfo, VGA_PEL_MSK, 0xff);
1491 WHDR (cinfo, 0xc5);
1492 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1493 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1494 offset = var->xres_virtual / 4;
1495 }
1496
1497
1498
1499
1500
1501
1502
1503 else {
1504 printk (KERN_ERR "cirrusfb: What's this?? requested color depth == %d.\n",
1505 var->bits_per_pixel);
1506 }
1507
1508 vga_wcrt (regbase, VGA_CRTC_OFFSET, offset & 0xff);
1509 tmp = 0x22;
1510 if (offset & 0x100)
1511 tmp |= 0x10;
1512
1513 vga_wcrt (regbase, CL_CRT1B, tmp);
1514
1515 if (cinfo->btype == BT_SD64 ||
1516 cinfo->btype == BT_PICASSO4 ||
1517 cinfo->btype == BT_ALPINE ||
1518 cinfo->btype == BT_GD5480)
1519 vga_wcrt (regbase, CL_CRT1D, 0x00);
1520
1521 vga_wcrt (regbase, VGA_CRTC_CURSOR_HI, 0);
1522 vga_wcrt (regbase, VGA_CRTC_CURSOR_LO, 0);
1523 vga_wcrt (regbase, VGA_CRTC_UNDERLINE, 0);
1524
1525 vga_wattr (regbase, VGA_ATC_MODE, 1);
1526 vga_wattr (regbase, VGA_ATC_OVERSCAN, 0);
1527 vga_wattr (regbase, VGA_ATC_PLANE_ENABLE, 15);
1528 vga_wattr (regbase, CL_AR33, 0);
1529 vga_wattr (regbase, VGA_ATC_COLOR_PAGE, 0);
1530
1531
1532
1533 AttrOn (cinfo);
1534
1535 vga_wgfx (regbase, VGA_GFX_SR_VALUE, 0);
1536 vga_wgfx (regbase, VGA_GFX_SR_ENABLE, 0);
1537 vga_wgfx (regbase, VGA_GFX_COMPARE_VALUE, 0);
1538 vga_wgfx (regbase, VGA_GFX_DATA_ROTATE, 0);
1539 vga_wgfx (regbase, VGA_GFX_PLANE_READ, 0);
1540 vga_wgfx (regbase, VGA_GFX_MISC, 1);
1541 vga_wgfx (regbase, VGA_GFX_COMPARE_MASK, 15);
1542 vga_wgfx (regbase, VGA_GFX_BIT_MASK, 255);
1543
1544 vga_wseq (regbase, CL_SEQR12, 0x0);
1545
1546
1547
1548 tmp = 0x01;
1549
1550
1551
1552
1553
1554
1555 vga_wseq (regbase, VGA_SEQ_CLOCK_MODE, tmp);
1556 DPRINTK ("CL_SEQR1: %d\n", tmp);
1557
1558 cinfo->currentmode = regs;
1559 info->fix.type = regs.type;
1560 info->fix.visual = regs.visual;
1561 info->fix.line_length = regs.line_length;
1562
1563
1564 cirrusfb_pan_display (var, info);
1565
1566#ifdef CIRRUSFB_DEBUG
1567 cirrusfb_dump ();
1568#endif
1569
1570 DPRINTK ("EXIT\n");
1571 return 0;
1572}
1573
1574
1575
1576int cirrusfb_set_par (struct fb_info *info)
1577{
1578 cirrusfb_set_par_foo (info);
1579 return cirrusfb_set_par_foo (info);
1580}
1581
1582int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1583 unsigned blue, unsigned transp,
1584 struct fb_info *info)
1585{
1586 struct cirrusfb_info *cinfo = info->par;
1587
1588 if (regno > 255)
1589 return -EINVAL;
1590
1591 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1592 u32 v;
1593 red >>= (16 - info->var.red.length);
1594 green >>= (16 - info->var.green.length);
1595 blue >>= (16 - info->var.blue.length);
1596
1597 if (regno>=16)
1598 return 1;
1599 v = (red << info->var.red.offset) |
1600 (green << info->var.green.offset) |
1601 (blue << info->var.blue.offset);
1602
1603 switch (info->var.bits_per_pixel) {
1604 case 8:
1605 ((u8*)(info->pseudo_palette))[regno] = v;
1606 break;
1607 case 16:
1608 ((u16*)(info->pseudo_palette))[regno] = v;
1609 break;
1610 case 24:
1611 case 32:
1612 ((u32*)(info->pseudo_palette))[regno] = v;
1613 break;
1614 }
1615 return 0;
1616 }
1617
1618 cinfo->palette[regno].red = red;
1619 cinfo->palette[regno].green = green;
1620 cinfo->palette[regno].blue = blue;
1621
1622 if (info->var.bits_per_pixel == 8) {
1623 WClut (cinfo, regno, red >> 10, green >> 10, blue >> 10);
1624 }
1625
1626 return 0;
1627
1628}
1629
1630
1631
1632
1633
1634
1635int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1636 struct fb_info *info)
1637{
1638 int xoffset = 0;
1639 int yoffset = 0;
1640 unsigned long base;
1641 unsigned char tmp = 0, tmp2 = 0, xpix;
1642 struct cirrusfb_info *cinfo = info->par;
1643
1644 DPRINTK ("ENTER\n");
1645 DPRINTK ("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1646
1647
1648
1649 if (var->vmode & FB_VMODE_YWRAP)
1650 return -EINVAL;
1651
1652 info->var.xoffset = var->xoffset;
1653 info->var.yoffset = var->yoffset;
1654
1655 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1656 yoffset = var->yoffset;
1657
1658 base = yoffset * cinfo->currentmode.line_length + xoffset;
1659
1660 if (info->var.bits_per_pixel == 1) {
1661
1662 xpix = (unsigned char) (var->xoffset % 8);
1663 } else {
1664 base /= 4;
1665 xpix = (unsigned char) ((xoffset % 4) * 2);
1666 }
1667
1668 cirrusfb_WaitBLT(cinfo->regbase);
1669
1670
1671 vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, (unsigned char) (base & 0xff));
1672 vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, (unsigned char) (base >> 8));
1673
1674
1675 if (base & 0x10000)
1676 tmp |= 0x01;
1677 if (base & 0x20000)
1678 tmp |= 0x04;
1679 if (base & 0x40000)
1680 tmp |= 0x08;
1681
1682 tmp2 = (vga_rcrt (cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
1683 vga_wcrt (cinfo->regbase, CL_CRT1B, tmp2);
1684
1685
1686 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
1687 tmp2 = 0;
1688 if (base & 0x80000)
1689 tmp2 = 0x80;
1690 vga_wcrt (cinfo->regbase, CL_CRT1D, tmp2);
1691 }
1692
1693
1694
1695 if (info->var.bits_per_pixel == 1)
1696 vga_wattr (cinfo->regbase, CL_AR33, xpix);
1697
1698 cirrusfb_WaitBLT (cinfo->regbase);
1699
1700 DPRINTK ("EXIT\n");
1701 return (0);
1702}
1703
1704
1705int cirrusfb_blank (int blank_mode, struct fb_info *info)
1706{
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717 unsigned char val;
1718 struct cirrusfb_info *cinfo = info->par;
1719 int current_mode = cinfo->blank_mode;
1720
1721 DPRINTK ("ENTER, blank mode = %d\n", blank_mode);
1722
1723 if (info->state != FBINFO_STATE_RUNNING ||
1724 current_mode == blank_mode) {
1725 DPRINTK ("EXIT, returning 0\n");
1726 return 0;
1727 }
1728
1729
1730 if (current_mode == FB_BLANK_NORMAL ||
1731 current_mode == FB_BLANK_UNBLANK) {
1732
1733 val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1734 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
1735
1736 vga_wgfx (cinfo->regbase, CL_GRE, 0x00);
1737 }
1738
1739
1740 if(blank_mode > FB_BLANK_NORMAL) {
1741
1742 val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1743 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
1744 }
1745
1746 switch (blank_mode) {
1747 case FB_BLANK_UNBLANK:
1748 case FB_BLANK_NORMAL:
1749 break;
1750 case FB_BLANK_VSYNC_SUSPEND:
1751 vga_wgfx (cinfo->regbase, CL_GRE, 0x04);
1752 break;
1753 case FB_BLANK_HSYNC_SUSPEND:
1754 vga_wgfx (cinfo->regbase, CL_GRE, 0x02);
1755 break;
1756 case FB_BLANK_POWERDOWN:
1757 vga_wgfx (cinfo->regbase, CL_GRE, 0x06);
1758 break;
1759 default:
1760 DPRINTK ("EXIT, returning 1\n");
1761 return 1;
1762 }
1763
1764 cinfo->blank_mode = blank_mode;
1765 DPRINTK ("EXIT, returning 0\n");
1766
1767
1768 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1769}
1770
1771
1772
1773
1774static void init_vgachip (struct cirrusfb_info *cinfo)
1775{
1776 const struct cirrusfb_board_info_rec *bi;
1777
1778 DPRINTK ("ENTER\n");
1779
1780 assert (cinfo != NULL);
1781
1782 bi = &cirrusfb_board_info[cinfo->btype];
1783
1784
1785 switch (cinfo->btype) {
1786 case BT_PICCOLO:
1787 WSFR (cinfo, 0x01);
1788 udelay (500);
1789 WSFR (cinfo, 0x51);
1790 udelay (500);
1791 break;
1792 case BT_PICASSO:
1793 WSFR2 (cinfo, 0xff);
1794 udelay (500);
1795 break;
1796 case BT_SD64:
1797 case BT_SPECTRUM:
1798 WSFR (cinfo, 0x1f);
1799 udelay (500);
1800 WSFR (cinfo, 0x4f);
1801 udelay (500);
1802 break;
1803 case BT_PICASSO4:
1804 vga_wcrt (cinfo->regbase, CL_CRT51, 0x00);
1805 mdelay (100);
1806 vga_wgfx (cinfo->regbase, CL_GR2F, 0x00);
1807 vga_wgfx (cinfo->regbase, CL_GR33, 0x00);
1808 vga_wgfx (cinfo->regbase, CL_GR31, 0x00);
1809 break;
1810
1811 case BT_GD5480:
1812 vga_wgfx (cinfo->regbase, CL_GR2F, 0x00);
1813 break;
1814
1815 case BT_ALPINE:
1816
1817 break;
1818
1819 default:
1820 printk (KERN_ERR "cirrusfb: Warning: Unknown board type\n");
1821 break;
1822 }
1823
1824 assert (cinfo->size > 0);
1825
1826
1827
1828
1829
1830 if (cinfo->btype != BT_PICASSO4) {
1831 WGen (cinfo, CL_VSSM, 0x10);
1832 WGen (cinfo, CL_POS102, 0x01);
1833 WGen (cinfo, CL_VSSM, 0x08);
1834
1835 if (cinfo->btype != BT_SD64)
1836 WGen (cinfo, CL_VSSM2, 0x01);
1837
1838 vga_wseq (cinfo->regbase, CL_SEQR0, 0x03);
1839
1840 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1841 WGen (cinfo, VGA_MIS_W, 0xc1);
1842
1843
1844 vga_wseq (cinfo->regbase, CL_SEQR6, 0x12);
1845
1846 vga_wgfx (cinfo->regbase, CL_GR31, 0x04);
1847
1848 switch (cinfo->btype) {
1849 case BT_GD5480:
1850 vga_wseq (cinfo->regbase, CL_SEQRF, 0x98);
1851 break;
1852 case BT_ALPINE:
1853 break;
1854 case BT_SD64:
1855 vga_wseq (cinfo->regbase, CL_SEQRF, 0xb8);
1856 break;
1857 default:
1858 vga_wseq (cinfo->regbase, CL_SEQR16, 0x0f);
1859 vga_wseq (cinfo->regbase, CL_SEQRF, 0xb0);
1860 break;
1861 }
1862 }
1863 vga_wseq (cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1864 vga_wseq (cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1865 vga_wseq (cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
1866
1867
1868 if (bi->init_sr07)
1869 vga_wseq (cinfo->regbase, CL_SEQR7, bi->sr07);
1870
1871
1872
1873 vga_wseq (cinfo->regbase, CL_SEQR10, 0x00);
1874 vga_wseq (cinfo->regbase, CL_SEQR11, 0x00);
1875 vga_wseq (cinfo->regbase, CL_SEQR12, 0x00);
1876 vga_wseq (cinfo->regbase, CL_SEQR13, 0x00);
1877
1878
1879 if (cinfo->btype != BT_PICASSO4) {
1880 vga_wseq (cinfo->regbase, CL_SEQR17, 0x00);
1881 vga_wseq (cinfo->regbase, CL_SEQR18, 0x02);
1882 }
1883
1884
1885 if (bi->init_sr1f)
1886 vga_wseq (cinfo->regbase, CL_SEQR1F, bi->sr1f);
1887
1888 vga_wcrt (cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1889 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1890 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1891 vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1892 vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1893 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1894 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1895
1896 vga_wcrt (cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1897 vga_wcrt (cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1898 vga_wcrt (cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1899
1900 vga_wcrt (cinfo->regbase, CL_CRT1B, 0x02);
1901
1902 vga_wgfx (cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1903 vga_wgfx (cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1904 vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1905 vga_wgfx (cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1906 vga_wgfx (cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1907 vga_wgfx (cinfo->regbase, VGA_GFX_MODE, 0x00);
1908 vga_wgfx (cinfo->regbase, VGA_GFX_MISC, 0x01);
1909 vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1910 vga_wgfx (cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1911 if (cinfo->btype == BT_ALPINE)
1912 vga_wgfx (cinfo->regbase, CL_GRB, 0x20);
1913 else
1914 vga_wgfx (cinfo->regbase, CL_GRB, 0x28);
1915
1916 vga_wgfx (cinfo->regbase, CL_GRC, 0xff);
1917 vga_wgfx (cinfo->regbase, CL_GRD, 0x00);
1918 vga_wgfx (cinfo->regbase, CL_GRE, 0x00);
1919
1920
1921
1922 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1923 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1924 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1925 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1926 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1927 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1928 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1929 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1930 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1931 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1932 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1933 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1934 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1935 vga_wattr (cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1936 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1937 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1938
1939 vga_wattr (cinfo->regbase, VGA_ATC_MODE, 0x01);
1940 vga_wattr (cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1941 vga_wattr (cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1942
1943 vga_wattr (cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1944
1945 WGen (cinfo, VGA_PEL_MSK, 0xff);
1946
1947 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1948 WGen (cinfo, VGA_MIS_W, 0xc3);
1949
1950 vga_wgfx (cinfo->regbase, CL_GR31, 0x04);
1951 vga_wgfx (cinfo->regbase, CL_GR31, 0x00);
1952
1953
1954 WHDR (cinfo, 0);
1955
1956 printk (KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n", cinfo->size);
1957 DPRINTK ("EXIT\n");
1958 return;
1959}
1960
1961static void switch_monitor (struct cirrusfb_info *cinfo, int on)
1962{
1963#ifdef CONFIG_ZORRO
1964 static int IsOn = 0;
1965
1966 DPRINTK ("ENTER\n");
1967
1968 if (cinfo->btype == BT_PICASSO4)
1969 return;
1970 if (cinfo->btype == BT_ALPINE)
1971 return;
1972 if (cinfo->btype == BT_GD5480)
1973 return;
1974 if (cinfo->btype == BT_PICASSO) {
1975 if ((on && !IsOn) || (!on && IsOn))
1976 WSFR (cinfo, 0xff);
1977
1978 DPRINTK ("EXIT\n");
1979 return;
1980 }
1981 if (on) {
1982 switch (cinfo->btype) {
1983 case BT_SD64:
1984 WSFR (cinfo, cinfo->SFR | 0x21);
1985 break;
1986 case BT_PICCOLO:
1987 WSFR (cinfo, cinfo->SFR | 0x28);
1988 break;
1989 case BT_SPECTRUM:
1990 WSFR (cinfo, 0x6f);
1991 break;
1992 default: break;
1993 }
1994 } else {
1995 switch (cinfo->btype) {
1996 case BT_SD64:
1997 WSFR (cinfo, cinfo->SFR & 0xde);
1998 break;
1999 case BT_PICCOLO:
2000 WSFR (cinfo, cinfo->SFR & 0xd7);
2001 break;
2002 case BT_SPECTRUM:
2003 WSFR (cinfo, 0x4f);
2004 break;
2005 default: break;
2006 }
2007 }
2008
2009 DPRINTK ("EXIT\n");
2010#endif
2011}
2012
2013
2014
2015
2016
2017
2018static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo,
2019 const struct fb_fillrect *region)
2020{
2021 int m;
2022 if(cinfo->info->var.bits_per_pixel == 1) {
2023 cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2024 region->dx / 8, region->dy,
2025 region->width / 8, region->height,
2026 region->color,
2027 cinfo->currentmode.line_length);
2028 } else {
2029 m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
2030 cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2031 region->dx * m, region->dy,
2032 region->width * m, region->height,
2033 region->color,
2034 cinfo->currentmode.line_length);
2035 }
2036 return;
2037}
2038
2039void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
2040{
2041 struct cirrusfb_info *cinfo = info->par;
2042 struct fb_fillrect modded;
2043 int vxres, vyres;
2044
2045 if (info->state != FBINFO_STATE_RUNNING)
2046 return;
2047 if (info->flags & FBINFO_HWACCEL_DISABLED) {
2048 cfb_fillrect(info, region);
2049 return;
2050 }
2051
2052 vxres = info->var.xres_virtual;
2053 vyres = info->var.yres_virtual;
2054
2055 memcpy(&modded, region, sizeof(struct fb_fillrect));
2056
2057 if(!modded.width || !modded.height ||
2058 modded.dx >= vxres || modded.dy >= vyres)
2059 return;
2060
2061 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
2062 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
2063
2064 cirrusfb_prim_fillrect(cinfo, &modded);
2065}
2066
2067static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo,
2068 const struct fb_copyarea *area)
2069{
2070 int m;
2071 if(cinfo->info->var.bits_per_pixel == 1) {
2072 cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2073 area->sx / 8, area->sy,
2074 area->dx / 8, area->dy,
2075 area->width / 8, area->height,
2076 cinfo->currentmode.line_length);
2077 } else {
2078 m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
2079 cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2080 area->sx * m, area->sy,
2081 area->dx * m, area->dy,
2082 area->width * m, area->height,
2083 cinfo->currentmode.line_length);
2084 }
2085 return;
2086}
2087
2088
2089void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
2090{
2091 struct cirrusfb_info *cinfo = info->par;
2092 struct fb_copyarea modded;
2093 u32 vxres, vyres;
2094 modded.sx = area->sx;
2095 modded.sy = area->sy;
2096 modded.dx = area->dx;
2097 modded.dy = area->dy;
2098 modded.width = area->width;
2099 modded.height = area->height;
2100
2101 if (info->state != FBINFO_STATE_RUNNING)
2102 return;
2103 if (info->flags & FBINFO_HWACCEL_DISABLED) {
2104 cfb_copyarea(info, area);
2105 return;
2106 }
2107
2108 vxres = info->var.xres_virtual;
2109 vyres = info->var.yres_virtual;
2110
2111 if(!modded.width || !modded.height ||
2112 modded.sx >= vxres || modded.sy >= vyres ||
2113 modded.dx >= vxres || modded.dy >= vyres)
2114 return;
2115
2116 if(modded.sx + modded.width > vxres) modded.width = vxres - modded.sx;
2117 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
2118 if(modded.sy + modded.height > vyres) modded.height = vyres - modded.sy;
2119 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
2120
2121 cirrusfb_prim_copyarea(cinfo, &modded);
2122}
2123
2124void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image)
2125{
2126 struct cirrusfb_info *cinfo = info->par;
2127
2128 cirrusfb_WaitBLT(cinfo->regbase);
2129 cfb_imageblit(info, image);
2130}
2131
2132
2133#ifdef CONFIG_PPC_PREP
2134#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
2135#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
2136static void get_prep_addrs (unsigned long *display, unsigned long *registers)
2137{
2138 DPRINTK ("ENTER\n");
2139
2140 *display = PREP_VIDEO_BASE;
2141 *registers = (unsigned long) PREP_IO_BASE;
2142
2143 DPRINTK ("EXIT\n");
2144}
2145
2146#endif
2147
2148
2149#ifdef CONFIG_PCI
2150static int release_io_ports = 0;
2151
2152
2153
2154
2155
2156static unsigned int cirrusfb_get_memsize (u8 __iomem *regbase)
2157{
2158 unsigned long mem;
2159 unsigned char SRF;
2160
2161 DPRINTK ("ENTER\n");
2162
2163 SRF = vga_rseq (regbase, CL_SEQRF);
2164 switch ((SRF & 0x18)) {
2165 case 0x08: mem = 512 * 1024; break;
2166 case 0x10: mem = 1024 * 1024; break;
2167
2168
2169 case 0x18: mem = 2048 * 1024; break;
2170 default: printk ("CLgenfb: Unknown memory size!\n");
2171 mem = 1024 * 1024;
2172 }
2173 if (SRF & 0x80) {
2174
2175
2176 mem *= 2;
2177 }
2178
2179
2180 DPRINTK ("EXIT\n");
2181 return mem;
2182}
2183
2184
2185
2186static void get_pci_addrs (const struct pci_dev *pdev,
2187 unsigned long *display, unsigned long *registers)
2188{
2189 assert (pdev != NULL);
2190 assert (display != NULL);
2191 assert (registers != NULL);
2192
2193 DPRINTK ("ENTER\n");
2194
2195 *display = 0;
2196 *registers = 0;
2197
2198
2199
2200 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
2201 *display = pci_resource_start(pdev, 1);
2202 *registers = pci_resource_start(pdev, 0);
2203 } else {
2204 *display = pci_resource_start(pdev, 0);
2205 *registers = pci_resource_start(pdev, 1);
2206 }
2207
2208 assert (*display != 0);
2209
2210 DPRINTK ("EXIT\n");
2211}
2212
2213
2214static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
2215{
2216 struct pci_dev *pdev = cinfo->pdev;
2217
2218 iounmap(cinfo->fbmem);
2219#if 0
2220 release_mem_region(0xA0000, 65535);
2221#endif
2222 if (release_io_ports)
2223 release_region(0x3C0, 32);
2224 pci_release_regions(pdev);
2225 framebuffer_release(cinfo->info);
2226 pci_disable_device(pdev);
2227}
2228#endif
2229
2230
2231#ifdef CONFIG_ZORRO
2232static void __devexit cirrusfb_zorro_unmap (struct cirrusfb_info *cinfo)
2233{
2234 zorro_release_device(cinfo->zdev);
2235
2236 if (cinfo->btype == BT_PICASSO4) {
2237 cinfo->regbase -= 0x600000;
2238 iounmap ((void *)cinfo->regbase);
2239 iounmap ((void *)cinfo->fbmem);
2240 } else {
2241 if (zorro_resource_start(cinfo->zdev) > 0x01000000)
2242 iounmap ((void *)cinfo->fbmem);
2243 }
2244 framebuffer_release(cinfo->info);
2245}
2246#endif
2247
2248static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2249{
2250 struct fb_info *info = cinfo->info;
2251 struct fb_var_screeninfo *var = &info->var;
2252
2253 info->par = cinfo;
2254 info->pseudo_palette = cinfo->pseudo_palette;
2255 info->flags = FBINFO_DEFAULT
2256 | FBINFO_HWACCEL_XPAN
2257 | FBINFO_HWACCEL_YPAN
2258 | FBINFO_HWACCEL_FILLRECT
2259 | FBINFO_HWACCEL_COPYAREA;
2260 if (noaccel)
2261 info->flags |= FBINFO_HWACCEL_DISABLED;
2262 info->fbops = &cirrusfb_ops;
2263 info->screen_base = cinfo->fbmem;
2264 if (cinfo->btype == BT_GD5480) {
2265 if (var->bits_per_pixel == 16)
2266 info->screen_base += 1 * MB_;
2267 if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32)
2268 info->screen_base += 2 * MB_;
2269 }
2270
2271
2272 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2273 sizeof(info->fix.id));
2274
2275
2276
2277 info->fix.smem_start = cinfo->fbmem_phys;
2278 info->fix.smem_len = (var->bits_per_pixel == 1) ? cinfo->size / 4 : cinfo->size;
2279 info->fix.type = cinfo->currentmode.type;
2280 info->fix.type_aux = 0;
2281 info->fix.visual = cinfo->currentmode.visual;
2282 info->fix.xpanstep = 1;
2283 info->fix.ypanstep = 1;
2284 info->fix.ywrapstep = 0;
2285 info->fix.line_length = cinfo->currentmode.line_length;
2286
2287
2288 info->fix.mmio_start = cinfo->fbregs_phys;
2289 info->fix.mmio_len = 0;
2290 info->fix.accel = FB_ACCEL_NONE;
2291
2292 fb_alloc_cmap(&info->cmap, 256, 0);
2293
2294 return 0;
2295}
2296
2297static int cirrusfb_register(struct cirrusfb_info *cinfo)
2298{
2299 struct fb_info *info;
2300 int err;
2301 cirrusfb_board_t btype;
2302
2303 DPRINTK ("ENTER\n");
2304
2305 printk (KERN_INFO "cirrusfb: Driver for Cirrus Logic based graphic boards, v" CIRRUSFB_VERSION "\n");
2306
2307 info = cinfo->info;
2308 btype = cinfo->btype;
2309
2310
2311 assert (btype != BT_NONE);
2312
2313 DPRINTK ("cirrusfb: (RAM start set to: 0x%p)\n", cinfo->fbmem);
2314
2315
2316
2317 info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
2318 info->var.activate = FB_ACTIVATE_NOW;
2319
2320 err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
2321 if (err < 0) {
2322
2323 DPRINTK("choking on default var... umm, no good.\n");
2324 goto err_unmap_cirrusfb;
2325 }
2326
2327
2328 cirrusfb_set_fbinfo(cinfo);
2329
2330 err = register_framebuffer(info);
2331 if (err < 0) {
2332 printk (KERN_ERR "cirrusfb: could not register fb device; err = %d!\n", err);
2333 goto err_dealloc_cmap;
2334 }
2335
2336 DPRINTK ("EXIT, returning 0\n");
2337 return 0;
2338
2339err_dealloc_cmap:
2340 fb_dealloc_cmap(&info->cmap);
2341err_unmap_cirrusfb:
2342 cinfo->unmap(cinfo);
2343 return err;
2344}
2345
2346static void __devexit cirrusfb_cleanup (struct fb_info *info)
2347{
2348 struct cirrusfb_info *cinfo = info->par;
2349 DPRINTK ("ENTER\n");
2350
2351 switch_monitor (cinfo, 0);
2352
2353 unregister_framebuffer (info);
2354 fb_dealloc_cmap (&info->cmap);
2355 printk ("Framebuffer unregistered\n");
2356 cinfo->unmap(cinfo);
2357
2358 DPRINTK ("EXIT\n");
2359}
2360
2361
2362#ifdef CONFIG_PCI
2363static int cirrusfb_pci_register (struct pci_dev *pdev,
2364 const struct pci_device_id *ent)
2365{
2366 struct cirrusfb_info *cinfo;
2367 struct fb_info *info;
2368 cirrusfb_board_t btype;
2369 unsigned long board_addr, board_size;
2370 int ret;
2371
2372 ret = pci_enable_device(pdev);
2373 if (ret < 0) {
2374 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2375 goto err_out;
2376 }
2377
2378 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2379 if (!info) {
2380 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2381 ret = -ENOMEM;
2382 goto err_disable;
2383 }
2384
2385 cinfo = info->par;
2386 cinfo->info = info;
2387 cinfo->pdev = pdev;
2388 cinfo->btype = btype = (cirrusfb_board_t) ent->driver_data;
2389
2390 DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n",
2391 pdev->resource[0].start, btype);
2392 DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start);
2393
2394 if(isPReP) {
2395 pci_write_config_dword (pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2396#ifdef CONFIG_PPC_PREP
2397 get_prep_addrs (&board_addr, &cinfo->fbregs_phys);
2398#endif
2399
2400 cinfo->regbase = (char __iomem *) cinfo->fbregs_phys;
2401 } else {
2402 DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
2403 get_pci_addrs (pdev, &board_addr, &cinfo->fbregs_phys);
2404 cinfo->regbase = NULL;
2405 }
2406
2407 DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, cinfo->fbregs_phys);
2408
2409 board_size = (btype == BT_GD5480) ?
2410 32 * MB_ : cirrusfb_get_memsize (cinfo->regbase);
2411
2412 ret = pci_request_regions(pdev, "cirrusfb");
2413 if (ret <0) {
2414 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n",
2415 board_addr);
2416 goto err_release_fb;
2417 }
2418#if 0
2419 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2420 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n"
2421,
2422 0xA0000L);
2423 ret = -EBUSY;
2424 goto err_release_regions;
2425 }
2426#endif
2427 if (request_region(0x3C0, 32, "cirrusfb"))
2428 release_io_ports = 1;
2429
2430 cinfo->fbmem = ioremap(board_addr, board_size);
2431 if (!cinfo->fbmem) {
2432 ret = -EIO;
2433 goto err_release_legacy;
2434 }
2435
2436 cinfo->fbmem_phys = board_addr;
2437 cinfo->size = board_size;
2438 cinfo->unmap = cirrusfb_pci_unmap;
2439
2440 printk (" RAM (%lu kB) at 0xx%lx, ", cinfo->size / KB_, board_addr);
2441 printk ("Cirrus Logic chipset on PCI bus\n");
2442 pci_set_drvdata(pdev, info);
2443
2444 return cirrusfb_register(cinfo);
2445
2446err_release_legacy:
2447 if (release_io_ports)
2448 release_region(0x3C0, 32);
2449#if 0
2450 release_mem_region(0xA0000, 65535);
2451err_release_regions:
2452#endif
2453 pci_release_regions(pdev);
2454err_release_fb:
2455 framebuffer_release(info);
2456err_disable:
2457 pci_disable_device(pdev);
2458err_out:
2459 return ret;
2460}
2461
2462void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev)
2463{
2464 struct fb_info *info = pci_get_drvdata(pdev);
2465 DPRINTK ("ENTER\n");
2466
2467 cirrusfb_cleanup (info);
2468
2469 DPRINTK ("EXIT\n");
2470}
2471
2472static struct pci_driver cirrusfb_pci_driver = {
2473 .name = "cirrusfb",
2474 .id_table = cirrusfb_pci_table,
2475 .probe = cirrusfb_pci_register,
2476 .remove = __devexit_p(cirrusfb_pci_unregister),
2477#ifdef CONFIG_PM
2478#if 0
2479 .suspend = cirrusfb_pci_suspend,
2480 .resume = cirrusfb_pci_resume,
2481#endif
2482#endif
2483};
2484#endif
2485
2486
2487#ifdef CONFIG_ZORRO
2488static int cirrusfb_zorro_register(struct zorro_dev *z,
2489 const struct zorro_device_id *ent)
2490{
2491 struct cirrusfb_info *cinfo;
2492 struct fb_info *info;
2493 cirrusfb_board_t btype;
2494 struct zorro_dev *z2 = NULL;
2495 unsigned long board_addr, board_size, size;
2496 int ret;
2497
2498 btype = ent->driver_data;
2499 if (cirrusfb_zorro_table2[btype].id2)
2500 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2501 size = cirrusfb_zorro_table2[btype].size;
2502 printk(KERN_INFO "cirrusfb: %s board detected; ",
2503 cirrusfb_board_info[btype].name);
2504
2505 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2506 if (!info) {
2507 printk (KERN_ERR "cirrusfb: could not allocate memory\n");
2508 ret = -ENOMEM;
2509 goto err_out;
2510 }
2511
2512 cinfo = info->par;
2513 cinfo->info = info;
2514 cinfo->btype = btype;
2515
2516 assert (z > 0);
2517 assert (z2 >= 0);
2518 assert (btype != BT_NONE);
2519
2520 cinfo->zdev = z;
2521 board_addr = zorro_resource_start(z);
2522 board_size = zorro_resource_len(z);
2523 cinfo->size = size;
2524
2525 if (!zorro_request_device(z, "cirrusfb")) {
2526 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n",
2527 board_addr);
2528 ret = -EBUSY;
2529 goto err_release_fb;
2530 }
2531
2532 printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
2533
2534 ret = -EIO;
2535
2536 if (btype == BT_PICASSO4) {
2537 printk (" REG at $%lx\n", board_addr + 0x600000);
2538
2539
2540
2541
2542
2543 cinfo->regbase = ioremap (board_addr, 16777216);
2544 if (!cinfo->regbase)
2545 goto err_release_region;
2546
2547 DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase);
2548 cinfo->regbase += 0x600000;
2549 cinfo->fbregs_phys = board_addr + 0x600000;
2550
2551 cinfo->fbmem_phys = board_addr + 16777216;
2552 cinfo->fbmem = ioremap (cinfo->fbmem_phys, 16777216);
2553 if (!cinfo->fbmem)
2554 goto err_unmap_regbase;
2555 } else {
2556 printk (" REG at $%lx\n", (unsigned long) z2->resource.start);
2557
2558 cinfo->fbmem_phys = board_addr;
2559 if (board_addr > 0x01000000)
2560 cinfo->fbmem = ioremap (board_addr, board_size);
2561 else
2562 cinfo->fbmem = (caddr_t) ZTWO_VADDR (board_addr);
2563 if (!cinfo->fbmem)
2564 goto err_release_region;
2565
2566
2567 cinfo->regbase = (caddr_t) ZTWO_VADDR (z2->resource.start);
2568 cinfo->fbregs_phys = z2->resource.start;
2569
2570 DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase);
2571 }
2572 cinfo->unmap = cirrusfb_zorro_unmap;
2573
2574 printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
2575 zorro_set_drvdata(z, info);
2576
2577 return cirrusfb_register(cinfo);
2578
2579err_unmap_regbase:
2580
2581 iounmap(cinfo->regbase - 0x600000);
2582err_release_region:
2583 release_region(board_addr, board_size);
2584err_release_fb:
2585 framebuffer_release(info);
2586err_out:
2587 return ret;
2588}
2589
2590void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2591{
2592 struct fb_info *info = zorro_get_drvdata(z);
2593 DPRINTK ("ENTER\n");
2594
2595 cirrusfb_cleanup (info);
2596
2597 DPRINTK ("EXIT\n");
2598}
2599
2600static struct zorro_driver cirrusfb_zorro_driver = {
2601 .name = "cirrusfb",
2602 .id_table = cirrusfb_zorro_table,
2603 .probe = cirrusfb_zorro_register,
2604 .remove = __devexit_p(cirrusfb_zorro_unregister),
2605};
2606#endif
2607
2608int __init cirrusfb_init(void)
2609{
2610 int error = 0;
2611
2612#ifndef MODULE
2613 char *option = NULL;
2614
2615 if (fb_get_options("cirrusfb", &option))
2616 return -ENODEV;
2617 cirrusfb_setup(option);
2618#endif
2619
2620#ifdef CONFIG_ZORRO
2621 error |= zorro_module_init(&cirrusfb_zorro_driver);
2622#endif
2623#ifdef CONFIG_PCI
2624 error |= pci_module_init(&cirrusfb_pci_driver);
2625#endif
2626 return error;
2627}
2628
2629
2630
2631#ifndef MODULE
2632int __init cirrusfb_setup(char *options) {
2633 char *this_opt, s[32];
2634 int i;
2635
2636 DPRINTK ("ENTER\n");
2637
2638 if (!options || !*options)
2639 return 0;
2640
2641 while ((this_opt = strsep (&options, ",")) != NULL) {
2642 if (!*this_opt) continue;
2643
2644 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
2645
2646 for (i = 0; i < NUM_TOTAL_MODES; i++) {
2647 sprintf (s, "mode:%s", cirrusfb_predefined[i].name);
2648 if (strcmp (this_opt, s) == 0)
2649 cirrusfb_def_mode = i;
2650 }
2651 if (!strcmp(this_opt, "noaccel"))
2652 noaccel = 1;
2653 }
2654 return 0;
2655}
2656#endif
2657
2658
2659
2660
2661
2662
2663MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2664MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2665MODULE_LICENSE("GPL");
2666
2667void __exit cirrusfb_exit (void)
2668{
2669#ifdef CONFIG_PCI
2670 pci_unregister_driver(&cirrusfb_pci_driver);
2671#endif
2672#ifdef CONFIG_ZORRO
2673 zorro_unregister_driver(&cirrusfb_zorro_driver);
2674#endif
2675}
2676
2677module_init(cirrusfb_init);
2678
2679#ifdef MODULE
2680module_exit(cirrusfb_exit);
2681#endif
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692static void WGen (const struct cirrusfb_info *cinfo,
2693 int regnum, unsigned char val)
2694{
2695 unsigned long regofs = 0;
2696
2697 if (cinfo->btype == BT_PICASSO) {
2698
2699
2700 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2701 regofs = 0xfff;
2702 }
2703
2704 vga_w (cinfo->regbase, regofs + regnum, val);
2705}
2706
2707
2708static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum)
2709{
2710 unsigned long regofs = 0;
2711
2712 if (cinfo->btype == BT_PICASSO) {
2713
2714
2715 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2716 regofs = 0xfff;
2717 }
2718
2719 return vga_r (cinfo->regbase, regofs + regnum);
2720}
2721
2722
2723static void AttrOn (const struct cirrusfb_info *cinfo)
2724{
2725 assert (cinfo != NULL);
2726
2727 DPRINTK ("ENTER\n");
2728
2729 if (vga_rcrt (cinfo->regbase, CL_CRT24) & 0x80) {
2730
2731
2732 vga_w (cinfo->regbase, VGA_ATT_IW,
2733 vga_r (cinfo->regbase, VGA_ATT_R));
2734 }
2735
2736
2737 vga_w (cinfo->regbase, VGA_ATT_IW, 0x33);
2738
2739
2740 vga_w (cinfo->regbase, VGA_ATT_IW, 0x00);
2741
2742 DPRINTK ("EXIT\n");
2743}
2744
2745
2746
2747
2748
2749
2750
2751static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val)
2752{
2753 unsigned char dummy;
2754
2755 if (cinfo->btype == BT_PICASSO) {
2756
2757
2758 WGen (cinfo, VGA_PEL_MSK, 0x00);
2759 udelay (200);
2760
2761 dummy = RGen (cinfo, VGA_PEL_IW);
2762 udelay (200);
2763 }
2764
2765
2766 dummy = RGen (cinfo, VGA_PEL_MSK);
2767 udelay (200);
2768 dummy = RGen (cinfo, VGA_PEL_MSK);
2769 udelay (200);
2770 dummy = RGen (cinfo, VGA_PEL_MSK);
2771 udelay (200);
2772 dummy = RGen (cinfo, VGA_PEL_MSK);
2773 udelay (200);
2774
2775 WGen (cinfo, VGA_PEL_MSK, val);
2776 udelay (200);
2777
2778 if (cinfo->btype == BT_PICASSO) {
2779
2780 dummy = RGen (cinfo, VGA_PEL_IW);
2781 udelay (200);
2782
2783
2784
2785 WGen (cinfo, VGA_PEL_MSK, 0xff);
2786 udelay (200);
2787 }
2788}
2789
2790
2791
2792static void WSFR (struct cirrusfb_info *cinfo, unsigned char val)
2793{
2794#ifdef CONFIG_ZORRO
2795 assert (cinfo->regbase != NULL);
2796 cinfo->SFR = val;
2797 z_writeb (val, cinfo->regbase + 0x8000);
2798#endif
2799}
2800
2801
2802static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val)
2803{
2804#ifdef CONFIG_ZORRO
2805
2806
2807 assert (cinfo->regbase != NULL);
2808 cinfo->SFR = val;
2809 z_writeb (val, cinfo->regbase + 0x9000);
2810#endif
2811}
2812
2813
2814
2815static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2816 unsigned char green, unsigned char blue)
2817{
2818 unsigned int data = VGA_PEL_D;
2819
2820
2821 vga_w (cinfo->regbase, VGA_PEL_IW, regnum);
2822
2823 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2824 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2825
2826 if (cinfo->btype == BT_PICASSO)
2827 data += 0xfff;
2828 vga_w (cinfo->regbase, data, red);
2829 vga_w (cinfo->regbase, data, green);
2830 vga_w (cinfo->regbase, data, blue);
2831 } else {
2832 vga_w (cinfo->regbase, data, blue);
2833 vga_w (cinfo->regbase, data, green);
2834 vga_w (cinfo->regbase, data, red);
2835 }
2836}
2837
2838
2839#if 0
2840
2841static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2842 unsigned char *green, unsigned char *blue)
2843{
2844 unsigned int data = VGA_PEL_D;
2845
2846 vga_w (cinfo->regbase, VGA_PEL_IR, regnum);
2847
2848 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2849 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2850 if (cinfo->btype == BT_PICASSO)
2851 data += 0xfff;
2852 *red = vga_r (cinfo->regbase, data);
2853 *green = vga_r (cinfo->regbase, data);
2854 *blue = vga_r (cinfo->regbase, data);
2855 } else {
2856 *blue = vga_r (cinfo->regbase, data);
2857 *green = vga_r (cinfo->regbase, data);
2858 *red = vga_r (cinfo->regbase, data);
2859 }
2860}
2861#endif
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871static void cirrusfb_WaitBLT (u8 __iomem *regbase)
2872{
2873
2874 while (vga_rgfx (regbase, CL_GR31) & 0x08)
2875 ;
2876}
2877
2878
2879
2880
2881
2882
2883
2884static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
2885 u_short curx, u_short cury, u_short destx, u_short desty,
2886 u_short width, u_short height, u_short line_length)
2887{
2888 u_short nwidth, nheight;
2889 u_long nsrc, ndest;
2890 u_char bltmode;
2891
2892 DPRINTK ("ENTER\n");
2893
2894 nwidth = width - 1;
2895 nheight = height - 1;
2896
2897 bltmode = 0x00;
2898
2899 if (cury <= desty) {
2900 if (cury == desty) {
2901
2902 if (curx < destx)
2903 bltmode |= 0x01;
2904 } else
2905 bltmode |= 0x01;
2906 }
2907 if (!bltmode) {
2908
2909 nsrc = (cury * line_length) + curx;
2910 ndest = (desty * line_length) + destx;
2911 } else {
2912
2913 nsrc = cury * line_length + curx + nheight * line_length + nwidth;
2914 ndest = desty * line_length + destx + nheight * line_length + nwidth;
2915 }
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930 cirrusfb_WaitBLT(regbase);
2931
2932
2933 vga_wgfx (regbase, CL_GR24, line_length & 0xff);
2934 vga_wgfx (regbase, CL_GR25, (line_length >> 8));
2935 vga_wgfx (regbase, CL_GR26, line_length & 0xff);
2936 vga_wgfx (regbase, CL_GR27, (line_length >> 8));
2937
2938
2939 vga_wgfx (regbase, CL_GR20, nwidth & 0xff);
2940 vga_wgfx (regbase, CL_GR21, (nwidth >> 8));
2941
2942
2943 vga_wgfx (regbase, CL_GR22, nheight & 0xff);
2944 vga_wgfx (regbase, CL_GR23, (nheight >> 8));
2945
2946
2947 vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff));
2948 vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8));
2949 vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16));
2950
2951
2952 vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2953 vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8));
2954 vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16));
2955
2956
2957 vga_wgfx (regbase, CL_GR30, bltmode);
2958
2959
2960 vga_wgfx (regbase, CL_GR32, 0x0d);
2961
2962
2963 vga_wgfx (regbase, CL_GR31, 0x02);
2964
2965 DPRINTK ("EXIT\n");
2966}
2967
2968
2969
2970
2971
2972
2973
2974
2975static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
2976 u_short x, u_short y, u_short width, u_short height,
2977 u_char color, u_short line_length)
2978{
2979 u_short nwidth, nheight;
2980 u_long ndest;
2981 u_char op;
2982
2983 DPRINTK ("ENTER\n");
2984
2985 nwidth = width - 1;
2986 nheight = height - 1;
2987
2988 ndest = (y * line_length) + x;
2989
2990 cirrusfb_WaitBLT(regbase);
2991
2992
2993 vga_wgfx (regbase, CL_GR24, line_length & 0xff);
2994 vga_wgfx (regbase, CL_GR25, (line_length >> 8));
2995 vga_wgfx (regbase, CL_GR26, line_length & 0xff);
2996 vga_wgfx (regbase, CL_GR27, (line_length >> 8));
2997
2998
2999 vga_wgfx (regbase, CL_GR20, nwidth & 0xff);
3000 vga_wgfx (regbase, CL_GR21, (nwidth >> 8));
3001
3002
3003 vga_wgfx (regbase, CL_GR22, nheight & 0xff);
3004 vga_wgfx (regbase, CL_GR23, (nheight >> 8));
3005
3006
3007 vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff));
3008 vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8));
3009 vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16));
3010
3011
3012 vga_wgfx (regbase, CL_GR2C, 0x00);
3013 vga_wgfx (regbase, CL_GR2D, 0x00);
3014 vga_wgfx (regbase, CL_GR2E, 0x00);
3015
3016
3017
3018 vga_wgfx (regbase, VGA_GFX_SR_VALUE, color);
3019 vga_wgfx (regbase, VGA_GFX_SR_ENABLE, color);
3020
3021 op = 0xc0;
3022 if (bits_per_pixel == 16) {
3023 vga_wgfx (regbase, CL_GR10, color);
3024 vga_wgfx (regbase, CL_GR11, color);
3025 op = 0x50;
3026 op = 0xd0;
3027 } else if (bits_per_pixel == 32) {
3028 vga_wgfx (regbase, CL_GR10, color);
3029 vga_wgfx (regbase, CL_GR11, color);
3030 vga_wgfx (regbase, CL_GR12, color);
3031 vga_wgfx (regbase, CL_GR13, color);
3032 vga_wgfx (regbase, CL_GR14, 0);
3033 vga_wgfx (regbase, CL_GR15, 0);
3034 op = 0x50;
3035 op = 0xf0;
3036 }
3037
3038 vga_wgfx (regbase, CL_GR30, op);
3039
3040
3041 vga_wgfx (regbase, CL_GR32, 0x0d);
3042
3043
3044 vga_wgfx (regbase, CL_GR31, 0x02);
3045
3046 DPRINTK ("EXIT\n");
3047}
3048
3049
3050
3051
3052
3053
3054static void bestclock (long freq, long *best, long *nom,
3055 long *den, long *div, long maxfreq)
3056{
3057 long n, h, d, f;
3058
3059 assert (best != NULL);
3060 assert (nom != NULL);
3061 assert (den != NULL);
3062 assert (div != NULL);
3063 assert (maxfreq > 0);
3064
3065 *nom = 0;
3066 *den = 0;
3067 *div = 0;
3068
3069 DPRINTK ("ENTER\n");
3070
3071 if (freq < 8000)
3072 freq = 8000;
3073
3074 if (freq > maxfreq)
3075 freq = maxfreq;
3076
3077 *best = 0;
3078 f = freq * 10;
3079
3080 for (n = 32; n < 128; n++) {
3081 d = (143181 * n) / f;
3082 if ((d >= 7) && (d <= 63)) {
3083 if (d > 31)
3084 d = (d / 2) * 2;
3085 h = (14318 * n) / d;
3086 if (abs (h - freq) < abs (*best - freq)) {
3087 *best = h;
3088 *nom = n;
3089 if (d < 32) {
3090 *den = d;
3091 *div = 0;
3092 } else {
3093 *den = d / 2;
3094 *div = 1;
3095 }
3096 }
3097 }
3098 d = ((143181 * n) + f - 1) / f;
3099 if ((d >= 7) && (d <= 63)) {
3100 if (d > 31)
3101 d = (d / 2) * 2;
3102 h = (14318 * n) / d;
3103 if (abs (h - freq) < abs (*best - freq)) {
3104 *best = h;
3105 *nom = n;
3106 if (d < 32) {
3107 *den = d;
3108 *div = 0;
3109 } else {
3110 *den = d / 2;
3111 *div = 1;
3112 }
3113 }
3114 }
3115 }
3116
3117 DPRINTK ("Best possible values for given frequency:\n");
3118 DPRINTK (" best: %ld kHz nom: %ld den: %ld div: %ld\n",
3119 freq, *nom, *den, *div);
3120
3121 DPRINTK ("EXIT\n");
3122}
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132#ifdef CIRRUSFB_DEBUG
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145static
3146void cirrusfb_dbg_print_byte (const char *name, unsigned char val)
3147{
3148 DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
3149 name, val,
3150 val & 0x80 ? '1' : '0',
3151 val & 0x40 ? '1' : '0',
3152 val & 0x20 ? '1' : '0',
3153 val & 0x10 ? '1' : '0',
3154 val & 0x08 ? '1' : '0',
3155 val & 0x04 ? '1' : '0',
3156 val & 0x02 ? '1' : '0',
3157 val & 0x01 ? '1' : '0');
3158}
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172static
3173void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...)
3174{
3175 va_list list;
3176 unsigned char val = 0;
3177 unsigned reg;
3178 char *name;
3179
3180 va_start (list, reg_class);
3181
3182 name = va_arg (list, char *);
3183 while (name != NULL) {
3184 reg = va_arg (list, int);
3185
3186 switch (reg_class) {
3187 case CRT:
3188 val = vga_rcrt (regbase, (unsigned char) reg);
3189 break;
3190 case SEQ:
3191 val = vga_rseq (regbase, (unsigned char) reg);
3192 break;
3193 default:
3194
3195 assert (FALSE);
3196 break;
3197 }
3198
3199 cirrusfb_dbg_print_byte (name, val);
3200
3201 name = va_arg (list, char *);
3202 }
3203
3204 va_end (list);
3205}
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215static
3216void cirrusfb_dump (void)
3217{
3218 cirrusfb_dbg_reg_dump (NULL);
3219}
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232static
3233void cirrusfb_dbg_reg_dump (caddr_t regbase)
3234{
3235 DPRINTK ("CIRRUSFB VGA CRTC register dump:\n");
3236
3237 cirrusfb_dbg_print_regs (regbase, CRT,
3238 "CR00", 0x00,
3239 "CR01", 0x01,
3240 "CR02", 0x02,
3241 "CR03", 0x03,
3242 "CR04", 0x04,
3243 "CR05", 0x05,
3244 "CR06", 0x06,
3245 "CR07", 0x07,
3246 "CR08", 0x08,
3247 "CR09", 0x09,
3248 "CR0A", 0x0A,
3249 "CR0B", 0x0B,
3250 "CR0C", 0x0C,
3251 "CR0D", 0x0D,
3252 "CR0E", 0x0E,
3253 "CR0F", 0x0F,
3254 "CR10", 0x10,
3255 "CR11", 0x11,
3256 "CR12", 0x12,
3257 "CR13", 0x13,
3258 "CR14", 0x14,
3259 "CR15", 0x15,
3260 "CR16", 0x16,
3261 "CR17", 0x17,
3262 "CR18", 0x18,
3263 "CR22", 0x22,
3264 "CR24", 0x24,
3265 "CR26", 0x26,
3266 "CR2D", 0x2D,
3267 "CR2E", 0x2E,
3268 "CR2F", 0x2F,
3269 "CR30", 0x30,
3270 "CR31", 0x31,
3271 "CR32", 0x32,
3272 "CR33", 0x33,
3273 "CR34", 0x34,
3274 "CR35", 0x35,
3275 "CR36", 0x36,
3276 "CR37", 0x37,
3277 "CR38", 0x38,
3278 "CR39", 0x39,
3279 "CR3A", 0x3A,
3280 "CR3B", 0x3B,
3281 "CR3C", 0x3C,
3282 "CR3D", 0x3D,
3283 "CR3E", 0x3E,
3284 "CR3F", 0x3F,
3285 NULL);
3286
3287 DPRINTK ("\n");
3288
3289 DPRINTK ("CIRRUSFB VGA SEQ register dump:\n");
3290
3291 cirrusfb_dbg_print_regs (regbase, SEQ,
3292 "SR00", 0x00,
3293 "SR01", 0x01,
3294 "SR02", 0x02,
3295 "SR03", 0x03,
3296 "SR04", 0x04,
3297 "SR08", 0x08,
3298 "SR09", 0x09,
3299 "SR0A", 0x0A,
3300 "SR0B", 0x0B,
3301 "SR0D", 0x0D,
3302 "SR10", 0x10,
3303 "SR11", 0x11,
3304 "SR12", 0x12,
3305 "SR13", 0x13,
3306 "SR14", 0x14,
3307 "SR15", 0x15,
3308 "SR16", 0x16,
3309 "SR17", 0x17,
3310 "SR18", 0x18,
3311 "SR19", 0x19,
3312 "SR1A", 0x1A,
3313 "SR1B", 0x1B,
3314 "SR1C", 0x1C,
3315 "SR1D", 0x1D,
3316 "SR1E", 0x1E,
3317 "SR1F", 0x1F,
3318 NULL);
3319
3320 DPRINTK ("\n");
3321}
3322
3323#endif
3324
3325