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