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
57#include <video/vga.h>
58#include <video/cirrus.h>
59
60
61
62
63
64
65
66
67
68
69
70#ifndef CIRRUSFB_NDEBUG
71#define assert(expr) \
72 if (!(expr)) { \
73 printk("Assertion failed! %s,%s,%s,line=%d\n", \
74 #expr, __FILE__, __func__, __LINE__); \
75 }
76#else
77#define assert(expr)
78#endif
79
80#define MB_ (1024 * 1024)
81
82
83
84
85
86
87
88
89enum cirrus_board {
90 BT_NONE = 0,
91 BT_SD64,
92 BT_PICCOLO,
93 BT_PICASSO,
94 BT_SPECTRUM,
95 BT_PICASSO4,
96 BT_ALPINE,
97 BT_GD5480,
98 BT_LAGUNA,
99 BT_LAGUNAB,
100};
101
102
103
104
105
106
107
108
109
110
111static const struct cirrusfb_board_info_rec {
112 char *name;
113 long maxclock[5];
114
115 bool init_sr07 : 1;
116 bool init_sr1f : 1;
117
118 bool scrn_start_bit19 : 1;
119
120
121 unsigned char sr07;
122 unsigned char sr07_1bpp;
123 unsigned char sr07_1bpp_mux;
124 unsigned char sr07_8bpp;
125 unsigned char sr07_8bpp_mux;
126
127 unsigned char sr1f;
128} cirrusfb_board_info[] = {
129 [BT_SD64] = {
130 .name = "CL SD64",
131 .maxclock = {
132
133
134 135100, 135100, 85500, 85500, 0
135 },
136 .init_sr07 = true,
137 .init_sr1f = true,
138 .scrn_start_bit19 = true,
139 .sr07 = 0xF0,
140 .sr07_1bpp = 0xF0,
141 .sr07_1bpp_mux = 0xF6,
142 .sr07_8bpp = 0xF1,
143 .sr07_8bpp_mux = 0xF7,
144 .sr1f = 0x1E
145 },
146 [BT_PICCOLO] = {
147 .name = "CL Piccolo",
148 .maxclock = {
149
150 90000, 90000, 90000, 90000, 90000
151 },
152 .init_sr07 = true,
153 .init_sr1f = true,
154 .scrn_start_bit19 = false,
155 .sr07 = 0x80,
156 .sr07_1bpp = 0x80,
157 .sr07_8bpp = 0x81,
158 .sr1f = 0x22
159 },
160 [BT_PICASSO] = {
161 .name = "CL Picasso",
162 .maxclock = {
163
164 90000, 90000, 90000, 90000, 90000
165 },
166 .init_sr07 = true,
167 .init_sr1f = true,
168 .scrn_start_bit19 = false,
169 .sr07 = 0x20,
170 .sr07_1bpp = 0x20,
171 .sr07_8bpp = 0x21,
172 .sr1f = 0x22
173 },
174 [BT_SPECTRUM] = {
175 .name = "CL Spectrum",
176 .maxclock = {
177
178 90000, 90000, 90000, 90000, 90000
179 },
180 .init_sr07 = true,
181 .init_sr1f = true,
182 .scrn_start_bit19 = false,
183 .sr07 = 0x80,
184 .sr07_1bpp = 0x80,
185 .sr07_8bpp = 0x81,
186 .sr1f = 0x22
187 },
188 [BT_PICASSO4] = {
189 .name = "CL Picasso4",
190 .maxclock = {
191 135100, 135100, 85500, 85500, 0
192 },
193 .init_sr07 = true,
194 .init_sr1f = false,
195 .scrn_start_bit19 = true,
196 .sr07 = 0xA0,
197 .sr07_1bpp = 0xA0,
198 .sr07_1bpp_mux = 0xA6,
199 .sr07_8bpp = 0xA1,
200 .sr07_8bpp_mux = 0xA7,
201 .sr1f = 0
202 },
203 [BT_ALPINE] = {
204 .name = "CL Alpine",
205 .maxclock = {
206
207 85500, 85500, 50000, 28500, 0
208 },
209 .init_sr07 = true,
210 .init_sr1f = true,
211 .scrn_start_bit19 = true,
212 .sr07 = 0xA0,
213 .sr07_1bpp = 0xA0,
214 .sr07_1bpp_mux = 0xA6,
215 .sr07_8bpp = 0xA1,
216 .sr07_8bpp_mux = 0xA7,
217 .sr1f = 0x1C
218 },
219 [BT_GD5480] = {
220 .name = "CL GD5480",
221 .maxclock = {
222 135100, 200000, 200000, 135100, 135100
223 },
224 .init_sr07 = true,
225 .init_sr1f = true,
226 .scrn_start_bit19 = true,
227 .sr07 = 0x10,
228 .sr07_1bpp = 0x11,
229 .sr07_8bpp = 0x11,
230 .sr1f = 0x1C
231 },
232 [BT_LAGUNA] = {
233 .name = "CL Laguna",
234 .maxclock = {
235
236 170000, 170000, 170000, 170000, 135100,
237 },
238 .init_sr07 = false,
239 .init_sr1f = false,
240 .scrn_start_bit19 = true,
241 },
242 [BT_LAGUNAB] = {
243 .name = "CL Laguna AGP",
244 .maxclock = {
245
246 170000, 250000, 170000, 170000, 135100,
247 },
248 .init_sr07 = false,
249 .init_sr1f = false,
250 .scrn_start_bit19 = true,
251 }
252};
253
254#ifdef CONFIG_PCI
255#define CHIP(id, btype) \
256 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
257
258static struct pci_device_id cirrusfb_pci_table[] = {
259 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
260 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
261 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
262 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE),
263 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
264 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
265 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480),
266 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4),
267 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA),
268 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA),
269 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB),
270 { 0, }
271};
272MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
273#undef CHIP
274#endif
275
276#ifdef CONFIG_ZORRO
277struct zorrocl {
278 enum cirrus_board type;
279 u32 regoffset;
280 u32 ramsize;
281
282 u32 ramoffset;
283 zorro_id ramid;
284 zorro_id ramid2;
285};
286
287static const struct zorrocl zcl_sd64 = {
288 .type = BT_SD64,
289 .ramid = ZORRO_PROD_HELFRICH_SD64_RAM,
290};
291
292static const struct zorrocl zcl_piccolo = {
293 .type = BT_PICCOLO,
294 .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
295};
296
297static const struct zorrocl zcl_picasso = {
298 .type = BT_PICASSO,
299 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
300};
301
302static const struct zorrocl zcl_spectrum = {
303 .type = BT_SPECTRUM,
304 .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
305};
306
307static const struct zorrocl zcl_picasso4_z3 = {
308 .type = BT_PICASSO4,
309 .regoffset = 0x00600000,
310 .ramsize = 4 * MB_,
311 .ramoffset = 0x01000000,
312};
313
314static const struct zorrocl zcl_picasso4_z2 = {
315 .type = BT_PICASSO4,
316 .regoffset = 0x10000,
317 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
318 .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
319};
320
321
322static const struct zorro_device_id cirrusfb_zorro_table[] = {
323 {
324 .id = ZORRO_PROD_HELFRICH_SD64_REG,
325 .driver_data = (unsigned long)&zcl_sd64,
326 }, {
327 .id = ZORRO_PROD_HELFRICH_PICCOLO_REG,
328 .driver_data = (unsigned long)&zcl_piccolo,
329 }, {
330 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
331 .driver_data = (unsigned long)&zcl_picasso,
332 }, {
333 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
334 .driver_data = (unsigned long)&zcl_spectrum,
335 }, {
336 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
337 .driver_data = (unsigned long)&zcl_picasso4_z3,
338 }, {
339 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG,
340 .driver_data = (unsigned long)&zcl_picasso4_z2,
341 },
342 { 0 }
343};
344MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
345#endif
346
347#ifdef CIRRUSFB_DEBUG
348enum cirrusfb_dbg_reg_class {
349 CRT,
350 SEQ
351};
352#endif
353
354
355struct cirrusfb_info {
356 u8 __iomem *regbase;
357 u8 __iomem *laguna_mmio;
358 enum cirrus_board btype;
359 unsigned char SFR;
360
361 int multiplexing;
362 int doubleVCLK;
363 int blank_mode;
364 u32 pseudo_palette[16];
365
366 void (*unmap)(struct fb_info *info);
367};
368
369static bool noaccel;
370static char *mode_option = "640x480@60";
371
372
373
374
375
376static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
377 struct fb_info *info);
378
379
380static void init_vgachip(struct fb_info *info);
381static void switch_monitor(struct cirrusfb_info *cinfo, int on);
382static void WGen(const struct cirrusfb_info *cinfo,
383 int regnum, unsigned char val);
384static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
385static void AttrOn(const struct cirrusfb_info *cinfo);
386static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
387static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
388static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
389static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
390 unsigned char red, unsigned char green, unsigned char blue);
391#if 0
392static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
393 unsigned char *red, unsigned char *green,
394 unsigned char *blue);
395#endif
396static void cirrusfb_WaitBLT(u8 __iomem *regbase);
397static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
398 u_short curx, u_short cury,
399 u_short destx, u_short desty,
400 u_short width, u_short height,
401 u_short line_length);
402static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
403 u_short x, u_short y,
404 u_short width, u_short height,
405 u32 fg_color, u32 bg_color,
406 u_short line_length, u_char blitmode);
407
408static void bestclock(long freq, int *nom, int *den, int *div);
409
410#ifdef CIRRUSFB_DEBUG
411static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
412static void cirrusfb_dbg_print_regs(struct fb_info *info,
413 caddr_t regbase,
414 enum cirrusfb_dbg_reg_class reg_class, ...);
415#endif
416
417
418
419
420
421static inline int is_laguna(const struct cirrusfb_info *cinfo)
422{
423 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
424}
425
426static int opencount;
427
428
429static int cirrusfb_open(struct fb_info *info, int user)
430{
431 if (opencount++ == 0)
432 switch_monitor(info->par, 1);
433 return 0;
434}
435
436
437static int cirrusfb_release(struct fb_info *info, int user)
438{
439 if (--opencount == 0)
440 switch_monitor(info->par, 0);
441 return 0;
442}
443
444
445
446
447
448
449static int cirrusfb_check_mclk(struct fb_info *info, long freq)
450{
451 struct cirrusfb_info *cinfo = info->par;
452 long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
453
454
455 mclk = (14318 * mclk) >> 3;
456 dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
457
458
459
460
461
462 if (abs(freq - mclk) < 250) {
463 dev_dbg(info->device, "Using VCLK = MCLK\n");
464 return 1;
465 } else if (abs(freq - (mclk / 2)) < 250) {
466 dev_dbg(info->device, "Using VCLK = MCLK/2\n");
467 return 2;
468 }
469
470 return 0;
471}
472
473static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
474 struct fb_info *info)
475{
476 long freq;
477 long maxclock;
478 struct cirrusfb_info *cinfo = info->par;
479 unsigned maxclockidx = var->bits_per_pixel >> 3;
480
481
482 freq = PICOS2KHZ(var->pixclock);
483
484 dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
485
486 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
487 cinfo->multiplexing = 0;
488
489
490
491 if (freq > maxclock) {
492 dev_err(info->device,
493 "Frequency greater than maxclock (%ld kHz)\n",
494 maxclock);
495 return -EINVAL;
496 }
497
498
499
500
501 if (var->bits_per_pixel == 8) {
502 switch (cinfo->btype) {
503 case BT_ALPINE:
504 case BT_SD64:
505 case BT_PICASSO4:
506 if (freq > 85500)
507 cinfo->multiplexing = 1;
508 break;
509 case BT_GD5480:
510 if (freq > 135100)
511 cinfo->multiplexing = 1;
512 break;
513
514 default:
515 break;
516 }
517 }
518
519
520
521 cinfo->doubleVCLK = 0;
522 if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
523 var->bits_per_pixel == 16) {
524 cinfo->doubleVCLK = 1;
525 }
526
527 return 0;
528}
529
530static int cirrusfb_check_var(struct fb_var_screeninfo *var,
531 struct fb_info *info)
532{
533 int yres;
534
535 unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
536 struct cirrusfb_info *cinfo = info->par;
537
538 switch (var->bits_per_pixel) {
539 case 1:
540 var->red.offset = 0;
541 var->red.length = 1;
542 var->green = var->red;
543 var->blue = var->red;
544 break;
545
546 case 8:
547 var->red.offset = 0;
548 var->red.length = 8;
549 var->green = var->red;
550 var->blue = var->red;
551 break;
552
553 case 16:
554 var->red.offset = 11;
555 var->green.offset = 5;
556 var->blue.offset = 0;
557 var->red.length = 5;
558 var->green.length = 6;
559 var->blue.length = 5;
560 break;
561
562 case 24:
563 var->red.offset = 16;
564 var->green.offset = 8;
565 var->blue.offset = 0;
566 var->red.length = 8;
567 var->green.length = 8;
568 var->blue.length = 8;
569 break;
570
571 default:
572 dev_dbg(info->device,
573 "Unsupported bpp size: %d\n", var->bits_per_pixel);
574 return -EINVAL;
575 }
576
577 if (var->xres_virtual < var->xres)
578 var->xres_virtual = var->xres;
579
580 if (var->yres_virtual == -1) {
581 var->yres_virtual = pixels / var->xres_virtual;
582
583 dev_info(info->device,
584 "virtual resolution set to maximum of %dx%d\n",
585 var->xres_virtual, var->yres_virtual);
586 }
587 if (var->yres_virtual < var->yres)
588 var->yres_virtual = var->yres;
589
590 if (var->xres_virtual * var->yres_virtual > pixels) {
591 dev_err(info->device, "mode %dx%dx%d rejected... "
592 "virtual resolution too high to fit into video memory!\n",
593 var->xres_virtual, var->yres_virtual,
594 var->bits_per_pixel);
595 return -EINVAL;
596 }
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_PCI
1855static int release_io_ports;
1856
1857
1858
1859
1860
1861static unsigned int cirrusfb_get_memsize(struct fb_info *info,
1862 u8 __iomem *regbase)
1863{
1864 unsigned long mem;
1865 struct cirrusfb_info *cinfo = info->par;
1866
1867 if (is_laguna(cinfo)) {
1868 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1869
1870 mem = ((SR14 & 7) + 1) << 20;
1871 } else {
1872 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1873 switch ((SRF & 0x18)) {
1874 case 0x08:
1875 mem = 512 * 1024;
1876 break;
1877 case 0x10:
1878 mem = 1024 * 1024;
1879 break;
1880
1881
1882
1883 case 0x18:
1884 mem = 2048 * 1024;
1885 break;
1886 default:
1887 dev_warn(info->device, "Unknown memory size!\n");
1888 mem = 1024 * 1024;
1889 }
1890
1891
1892
1893 if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1894 mem *= 2;
1895 }
1896
1897
1898 return mem;
1899}
1900
1901static void get_pci_addrs(const struct pci_dev *pdev,
1902 unsigned long *display, unsigned long *registers)
1903{
1904 assert(pdev != NULL);
1905 assert(display != NULL);
1906 assert(registers != NULL);
1907
1908 *display = 0;
1909 *registers = 0;
1910
1911
1912
1913 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1914 *display = pci_resource_start(pdev, 1);
1915 *registers = pci_resource_start(pdev, 0);
1916 } else {
1917 *display = pci_resource_start(pdev, 0);
1918 *registers = pci_resource_start(pdev, 1);
1919 }
1920
1921 assert(*display != 0);
1922}
1923
1924static void cirrusfb_pci_unmap(struct fb_info *info)
1925{
1926 struct pci_dev *pdev = to_pci_dev(info->device);
1927 struct cirrusfb_info *cinfo = info->par;
1928
1929 if (cinfo->laguna_mmio == NULL)
1930 iounmap(cinfo->laguna_mmio);
1931 iounmap(info->screen_base);
1932#if 0
1933 release_mem_region(0xA0000, 65535);
1934#endif
1935 if (release_io_ports)
1936 release_region(0x3C0, 32);
1937 pci_release_regions(pdev);
1938}
1939#endif
1940
1941#ifdef CONFIG_ZORRO
1942static void cirrusfb_zorro_unmap(struct fb_info *info)
1943{
1944 struct cirrusfb_info *cinfo = info->par;
1945 struct zorro_dev *zdev = to_zorro_dev(info->device);
1946
1947 if (info->fix.smem_start > 16 * MB_)
1948 iounmap(info->screen_base);
1949 if (info->fix.mmio_start > 16 * MB_)
1950 iounmap(cinfo->regbase);
1951
1952 zorro_release_device(zdev);
1953}
1954#endif
1955
1956
1957static struct fb_ops cirrusfb_ops = {
1958 .owner = THIS_MODULE,
1959 .fb_open = cirrusfb_open,
1960 .fb_release = cirrusfb_release,
1961 .fb_setcolreg = cirrusfb_setcolreg,
1962 .fb_check_var = cirrusfb_check_var,
1963 .fb_set_par = cirrusfb_set_par,
1964 .fb_pan_display = cirrusfb_pan_display,
1965 .fb_blank = cirrusfb_blank,
1966 .fb_fillrect = cirrusfb_fillrect,
1967 .fb_copyarea = cirrusfb_copyarea,
1968 .fb_sync = cirrusfb_sync,
1969 .fb_imageblit = cirrusfb_imageblit,
1970};
1971
1972static int cirrusfb_set_fbinfo(struct fb_info *info)
1973{
1974 struct cirrusfb_info *cinfo = info->par;
1975 struct fb_var_screeninfo *var = &info->var;
1976
1977 info->pseudo_palette = cinfo->pseudo_palette;
1978 info->flags = FBINFO_DEFAULT
1979 | FBINFO_HWACCEL_XPAN
1980 | FBINFO_HWACCEL_YPAN
1981 | FBINFO_HWACCEL_FILLRECT
1982 | FBINFO_HWACCEL_IMAGEBLIT
1983 | FBINFO_HWACCEL_COPYAREA;
1984 if (noaccel || is_laguna(cinfo)) {
1985 info->flags |= FBINFO_HWACCEL_DISABLED;
1986 info->fix.accel = FB_ACCEL_NONE;
1987 } else
1988 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
1989
1990 info->fbops = &cirrusfb_ops;
1991
1992 if (cinfo->btype == BT_GD5480) {
1993 if (var->bits_per_pixel == 16)
1994 info->screen_base += 1 * MB_;
1995 if (var->bits_per_pixel == 32)
1996 info->screen_base += 2 * MB_;
1997 }
1998
1999
2000 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2001 sizeof(info->fix.id));
2002
2003
2004
2005 info->fix.smem_len = info->screen_size;
2006 if (var->bits_per_pixel == 1)
2007 info->fix.smem_len /= 4;
2008 info->fix.type_aux = 0;
2009 info->fix.xpanstep = 1;
2010 info->fix.ypanstep = 1;
2011 info->fix.ywrapstep = 0;
2012
2013
2014 info->fix.mmio_len = 0;
2015
2016 fb_alloc_cmap(&info->cmap, 256, 0);
2017
2018 return 0;
2019}
2020
2021static int cirrusfb_register(struct fb_info *info)
2022{
2023 struct cirrusfb_info *cinfo = info->par;
2024 int err;
2025
2026
2027 assert(cinfo->btype != BT_NONE);
2028
2029
2030 cirrusfb_set_fbinfo(info);
2031
2032 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2033
2034 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2035 if (!err) {
2036 dev_dbg(info->device, "wrong initial video mode\n");
2037 err = -EINVAL;
2038 goto err_dealloc_cmap;
2039 }
2040
2041 info->var.activate = FB_ACTIVATE_NOW;
2042
2043 err = cirrusfb_check_var(&info->var, info);
2044 if (err < 0) {
2045
2046 dev_dbg(info->device,
2047 "choking on default var... umm, no good.\n");
2048 goto err_dealloc_cmap;
2049 }
2050
2051 err = register_framebuffer(info);
2052 if (err < 0) {
2053 dev_err(info->device,
2054 "could not register fb device; err = %d!\n", err);
2055 goto err_dealloc_cmap;
2056 }
2057
2058 return 0;
2059
2060err_dealloc_cmap:
2061 fb_dealloc_cmap(&info->cmap);
2062 return err;
2063}
2064
2065static void cirrusfb_cleanup(struct fb_info *info)
2066{
2067 struct cirrusfb_info *cinfo = info->par;
2068
2069 switch_monitor(cinfo, 0);
2070 unregister_framebuffer(info);
2071 fb_dealloc_cmap(&info->cmap);
2072 dev_dbg(info->device, "Framebuffer unregistered\n");
2073 cinfo->unmap(info);
2074 framebuffer_release(info);
2075}
2076
2077#ifdef CONFIG_PCI
2078static int cirrusfb_pci_register(struct pci_dev *pdev,
2079 const struct pci_device_id *ent)
2080{
2081 struct cirrusfb_info *cinfo;
2082 struct fb_info *info;
2083 unsigned long board_addr, board_size;
2084 int ret;
2085
2086 ret = pci_enable_device(pdev);
2087 if (ret < 0) {
2088 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2089 goto err_out;
2090 }
2091
2092 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2093 if (!info) {
2094 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2095 ret = -ENOMEM;
2096 goto err_out;
2097 }
2098
2099 cinfo = info->par;
2100 cinfo->btype = (enum cirrus_board) ent->driver_data;
2101
2102 dev_dbg(info->device,
2103 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2104 (unsigned long long)pdev->resource[0].start, cinfo->btype);
2105 dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2106 (unsigned long long)pdev->resource[1].start);
2107
2108 dev_dbg(info->device,
2109 "Attempt to get PCI info for Cirrus Graphics Card\n");
2110 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2111
2112 cinfo->regbase = NULL;
2113 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2114
2115 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2116 board_addr, info->fix.mmio_start);
2117
2118 board_size = (cinfo->btype == BT_GD5480) ?
2119 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2120
2121 ret = pci_request_regions(pdev, "cirrusfb");
2122 if (ret < 0) {
2123 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2124 board_addr);
2125 goto err_release_fb;
2126 }
2127#if 0
2128 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2129 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2130 0xA0000L);
2131 ret = -EBUSY;
2132 goto err_release_regions;
2133 }
2134#endif
2135 if (request_region(0x3C0, 32, "cirrusfb"))
2136 release_io_ports = 1;
2137
2138 info->screen_base = ioremap(board_addr, board_size);
2139 if (!info->screen_base) {
2140 ret = -EIO;
2141 goto err_release_legacy;
2142 }
2143
2144 info->fix.smem_start = board_addr;
2145 info->screen_size = board_size;
2146 cinfo->unmap = cirrusfb_pci_unmap;
2147
2148 dev_info(info->device,
2149 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2150 info->screen_size >> 10, board_addr);
2151 pci_set_drvdata(pdev, info);
2152
2153 ret = cirrusfb_register(info);
2154 if (!ret)
2155 return 0;
2156
2157 iounmap(info->screen_base);
2158err_release_legacy:
2159 if (release_io_ports)
2160 release_region(0x3C0, 32);
2161#if 0
2162 release_mem_region(0xA0000, 65535);
2163err_release_regions:
2164#endif
2165 pci_release_regions(pdev);
2166err_release_fb:
2167 if (cinfo->laguna_mmio != NULL)
2168 iounmap(cinfo->laguna_mmio);
2169 framebuffer_release(info);
2170err_out:
2171 return ret;
2172}
2173
2174static void cirrusfb_pci_unregister(struct pci_dev *pdev)
2175{
2176 struct fb_info *info = pci_get_drvdata(pdev);
2177
2178 cirrusfb_cleanup(info);
2179}
2180
2181static struct pci_driver cirrusfb_pci_driver = {
2182 .name = "cirrusfb",
2183 .id_table = cirrusfb_pci_table,
2184 .probe = cirrusfb_pci_register,
2185 .remove = cirrusfb_pci_unregister,
2186#ifdef CONFIG_PM
2187#if 0
2188 .suspend = cirrusfb_pci_suspend,
2189 .resume = cirrusfb_pci_resume,
2190#endif
2191#endif
2192};
2193#endif
2194
2195#ifdef CONFIG_ZORRO
2196static int cirrusfb_zorro_register(struct zorro_dev *z,
2197 const struct zorro_device_id *ent)
2198{
2199 struct fb_info *info;
2200 int error;
2201 const struct zorrocl *zcl;
2202 enum cirrus_board btype;
2203 unsigned long regbase, ramsize, rambase;
2204 struct cirrusfb_info *cinfo;
2205
2206 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2207 if (!info) {
2208 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2209 return -ENOMEM;
2210 }
2211
2212 zcl = (const struct zorrocl *)ent->driver_data;
2213 btype = zcl->type;
2214 regbase = zorro_resource_start(z) + zcl->regoffset;
2215 ramsize = zcl->ramsize;
2216 if (ramsize) {
2217 rambase = zorro_resource_start(z) + zcl->ramoffset;
2218 if (zorro_resource_len(z) == 64 * MB_) {
2219
2220 rambase += zcl->ramoffset;
2221 }
2222 } else {
2223 struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2224 if (!ram || !zorro_resource_len(ram)) {
2225 dev_err(info->device, "No video RAM found\n");
2226 error = -ENODEV;
2227 goto err_release_fb;
2228 }
2229 rambase = zorro_resource_start(ram);
2230 ramsize = zorro_resource_len(ram);
2231 if (zcl->ramid2 &&
2232 (ram = zorro_find_device(zcl->ramid2, NULL))) {
2233 if (zorro_resource_start(ram) != rambase + ramsize) {
2234 dev_warn(info->device,
2235 "Skipping non-contiguous RAM at %pR\n",
2236 &ram->resource);
2237 } else {
2238 ramsize += zorro_resource_len(ram);
2239 }
2240 }
2241 }
2242
2243 dev_info(info->device,
2244 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2245 cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2246 rambase);
2247
2248 if (!zorro_request_device(z, "cirrusfb")) {
2249 dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2250 error = -EBUSY;
2251 goto err_release_fb;
2252 }
2253
2254 cinfo = info->par;
2255 cinfo->btype = btype;
2256
2257 info->fix.mmio_start = regbase;
2258 cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2259 : ZTWO_VADDR(regbase);
2260 if (!cinfo->regbase) {
2261 dev_err(info->device, "Cannot map registers\n");
2262 error = -EIO;
2263 goto err_release_dev;
2264 }
2265
2266 info->fix.smem_start = rambase;
2267 info->screen_size = ramsize;
2268 info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2269 : ZTWO_VADDR(rambase);
2270 if (!info->screen_base) {
2271 dev_err(info->device, "Cannot map video RAM\n");
2272 error = -EIO;
2273 goto err_unmap_reg;
2274 }
2275
2276 cinfo->unmap = cirrusfb_zorro_unmap;
2277
2278 dev_info(info->device,
2279 "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2280 ramsize / MB_, rambase);
2281
2282
2283 if (cirrusfb_board_info[btype].init_sr1f)
2284 vga_wseq(cinfo->regbase, CL_SEQR1F,
2285 cirrusfb_board_info[btype].sr1f);
2286
2287 error = cirrusfb_register(info);
2288 if (error) {
2289 dev_err(info->device, "Failed to register device, error %d\n",
2290 error);
2291 goto err_unmap_ram;
2292 }
2293
2294 zorro_set_drvdata(z, info);
2295 return 0;
2296
2297err_unmap_ram:
2298 if (rambase > 16 * MB_)
2299 iounmap(info->screen_base);
2300
2301err_unmap_reg:
2302 if (regbase > 16 * MB_)
2303 iounmap(cinfo->regbase);
2304err_release_dev:
2305 zorro_release_device(z);
2306err_release_fb:
2307 framebuffer_release(info);
2308 return error;
2309}
2310
2311void cirrusfb_zorro_unregister(struct zorro_dev *z)
2312{
2313 struct fb_info *info = zorro_get_drvdata(z);
2314
2315 cirrusfb_cleanup(info);
2316 zorro_set_drvdata(z, NULL);
2317}
2318
2319static struct zorro_driver cirrusfb_zorro_driver = {
2320 .name = "cirrusfb",
2321 .id_table = cirrusfb_zorro_table,
2322 .probe = cirrusfb_zorro_register,
2323 .remove = cirrusfb_zorro_unregister,
2324};
2325#endif
2326
2327#ifndef MODULE
2328static int __init cirrusfb_setup(char *options)
2329{
2330 char *this_opt;
2331
2332 if (!options || !*options)
2333 return 0;
2334
2335 while ((this_opt = strsep(&options, ",")) != NULL) {
2336 if (!*this_opt)
2337 continue;
2338
2339 if (!strcmp(this_opt, "noaccel"))
2340 noaccel = 1;
2341 else if (!strncmp(this_opt, "mode:", 5))
2342 mode_option = this_opt + 5;
2343 else
2344 mode_option = this_opt;
2345 }
2346 return 0;
2347}
2348#endif
2349
2350
2351
2352
2353
2354MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2355MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2356MODULE_LICENSE("GPL");
2357
2358static int __init cirrusfb_init(void)
2359{
2360 int error = 0;
2361
2362#ifndef MODULE
2363 char *option = NULL;
2364
2365 if (fb_get_options("cirrusfb", &option))
2366 return -ENODEV;
2367 cirrusfb_setup(option);
2368#endif
2369
2370#ifdef CONFIG_ZORRO
2371 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2372#endif
2373#ifdef CONFIG_PCI
2374 error |= pci_register_driver(&cirrusfb_pci_driver);
2375#endif
2376 return error;
2377}
2378
2379static void __exit cirrusfb_exit(void)
2380{
2381#ifdef CONFIG_PCI
2382 pci_unregister_driver(&cirrusfb_pci_driver);
2383#endif
2384#ifdef CONFIG_ZORRO
2385 zorro_unregister_driver(&cirrusfb_zorro_driver);
2386#endif
2387}
2388
2389module_init(cirrusfb_init);
2390
2391module_param(mode_option, charp, 0);
2392MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2393module_param(noaccel, bool, 0);
2394MODULE_PARM_DESC(noaccel, "Disable acceleration");
2395
2396#ifdef MODULE
2397module_exit(cirrusfb_exit);
2398#endif
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408static void WGen(const struct cirrusfb_info *cinfo,
2409 int regnum, unsigned char val)
2410{
2411 unsigned long regofs = 0;
2412
2413 if (cinfo->btype == BT_PICASSO) {
2414
2415
2416
2417 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2418 regofs = 0xfff;
2419 }
2420
2421 vga_w(cinfo->regbase, regofs + regnum, val);
2422}
2423
2424
2425static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2426{
2427 unsigned long regofs = 0;
2428
2429 if (cinfo->btype == BT_PICASSO) {
2430
2431
2432
2433 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2434 regofs = 0xfff;
2435 }
2436
2437 return vga_r(cinfo->regbase, regofs + regnum);
2438}
2439
2440
2441static void AttrOn(const struct cirrusfb_info *cinfo)
2442{
2443 assert(cinfo != NULL);
2444
2445 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2446
2447
2448 vga_w(cinfo->regbase, VGA_ATT_IW,
2449 vga_r(cinfo->regbase, VGA_ATT_R));
2450 }
2451
2452
2453 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2454
2455
2456 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2457}
2458
2459
2460
2461
2462
2463
2464
2465static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2466{
2467 unsigned char dummy;
2468
2469 if (is_laguna(cinfo))
2470 return;
2471 if (cinfo->btype == BT_PICASSO) {
2472
2473
2474 WGen(cinfo, VGA_PEL_MSK, 0x00);
2475 udelay(200);
2476
2477 dummy = RGen(cinfo, VGA_PEL_IW);
2478 udelay(200);
2479 }
2480
2481
2482 dummy = RGen(cinfo, VGA_PEL_MSK);
2483 udelay(200);
2484 dummy = RGen(cinfo, VGA_PEL_MSK);
2485 udelay(200);
2486 dummy = RGen(cinfo, VGA_PEL_MSK);
2487 udelay(200);
2488 dummy = RGen(cinfo, VGA_PEL_MSK);
2489 udelay(200);
2490
2491 WGen(cinfo, VGA_PEL_MSK, val);
2492 udelay(200);
2493
2494 if (cinfo->btype == BT_PICASSO) {
2495
2496 dummy = RGen(cinfo, VGA_PEL_IW);
2497 udelay(200);
2498
2499
2500
2501 WGen(cinfo, VGA_PEL_MSK, 0xff);
2502 udelay(200);
2503 }
2504}
2505
2506
2507static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2508{
2509#ifdef CONFIG_ZORRO
2510 assert(cinfo->regbase != NULL);
2511 cinfo->SFR = val;
2512 z_writeb(val, cinfo->regbase + 0x8000);
2513#endif
2514}
2515
2516
2517static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2518{
2519#ifdef CONFIG_ZORRO
2520
2521
2522 assert(cinfo->regbase != NULL);
2523 cinfo->SFR = val;
2524 z_writeb(val, cinfo->regbase + 0x9000);
2525#endif
2526}
2527
2528
2529static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2530 unsigned char green, unsigned char blue)
2531{
2532 unsigned int data = VGA_PEL_D;
2533
2534
2535 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2536
2537 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2538 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2539 cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2540
2541 if (cinfo->btype == BT_PICASSO)
2542 data += 0xfff;
2543 vga_w(cinfo->regbase, data, red);
2544 vga_w(cinfo->regbase, data, green);
2545 vga_w(cinfo->regbase, data, blue);
2546 } else {
2547 vga_w(cinfo->regbase, data, blue);
2548 vga_w(cinfo->regbase, data, green);
2549 vga_w(cinfo->regbase, data, red);
2550 }
2551}
2552
2553#if 0
2554
2555static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2556 unsigned char *green, unsigned char *blue)
2557{
2558 unsigned int data = VGA_PEL_D;
2559
2560 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2561
2562 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2563 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2564 if (cinfo->btype == BT_PICASSO)
2565 data += 0xfff;
2566 *red = vga_r(cinfo->regbase, data);
2567 *green = vga_r(cinfo->regbase, data);
2568 *blue = vga_r(cinfo->regbase, data);
2569 } else {
2570 *blue = vga_r(cinfo->regbase, data);
2571 *green = vga_r(cinfo->regbase, data);
2572 *red = vga_r(cinfo->regbase, data);
2573 }
2574}
2575#endif
2576
2577
2578
2579
2580
2581
2582
2583
2584static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2585{
2586 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2587 cpu_relax();
2588}
2589
2590
2591
2592
2593
2594
2595
2596static void cirrusfb_set_blitter(u8 __iomem *regbase,
2597 u_short nwidth, u_short nheight,
2598 u_long nsrc, u_long ndest,
2599 u_short bltmode, u_short line_length)
2600
2601{
2602
2603
2604 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2605
2606 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2607
2608 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2609
2610 vga_wgfx(regbase, CL_GR27, line_length >> 8);
2611
2612
2613
2614 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2615
2616 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2617
2618
2619
2620 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2621
2622 vga_wgfx(regbase, CL_GR23, nheight >> 8);
2623
2624
2625
2626 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2627
2628 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2629
2630 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2631
2632
2633
2634 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2635
2636 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2637
2638 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2639
2640
2641 vga_wgfx(regbase, CL_GR30, bltmode);
2642
2643
2644 vga_wgfx(regbase, CL_GR32, 0x0d);
2645
2646
2647 vga_wgfx(regbase, CL_GR31, 0x02);
2648}
2649
2650
2651
2652
2653
2654
2655
2656static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2657 u_short curx, u_short cury,
2658 u_short destx, u_short desty,
2659 u_short width, u_short height,
2660 u_short line_length)
2661{
2662 u_short nwidth = width - 1;
2663 u_short nheight = height - 1;
2664 u_long nsrc, ndest;
2665 u_char bltmode;
2666
2667 bltmode = 0x00;
2668
2669 if (cury <= desty) {
2670 if (cury == desty) {
2671
2672 if (curx < destx)
2673 bltmode |= 0x01;
2674 } else
2675 bltmode |= 0x01;
2676 }
2677
2678 nsrc = (cury * line_length) + curx;
2679 ndest = (desty * line_length) + destx;
2680 if (bltmode) {
2681
2682
2683
2684 nsrc += nheight * line_length + nwidth;
2685 ndest += nheight * line_length + nwidth;
2686 }
2687
2688 cirrusfb_WaitBLT(regbase);
2689
2690 cirrusfb_set_blitter(regbase, nwidth, nheight,
2691 nsrc, ndest, bltmode, line_length);
2692}
2693
2694
2695
2696
2697
2698
2699
2700static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2701 u_short x, u_short y, u_short width, u_short height,
2702 u32 fg_color, u32 bg_color, u_short line_length,
2703 u_char blitmode)
2704{
2705 u_long ndest = (y * line_length) + x;
2706 u_char op;
2707
2708 cirrusfb_WaitBLT(regbase);
2709
2710
2711
2712 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2713 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2714
2715 op = 0x80;
2716 if (bits_per_pixel >= 16) {
2717 vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2718 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2719 op = 0x90;
2720 }
2721 if (bits_per_pixel >= 24) {
2722 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2723 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2724 op = 0xa0;
2725 }
2726 if (bits_per_pixel == 32) {
2727 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2728 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2729 op = 0xb0;
2730 }
2731 cirrusfb_set_blitter(regbase, width - 1, height - 1,
2732 0, ndest, op | blitmode, line_length);
2733}
2734
2735
2736
2737
2738
2739static void bestclock(long freq, int *nom, int *den, int *div)
2740{
2741 int n, d;
2742 long h, diff;
2743
2744 assert(nom != NULL);
2745 assert(den != NULL);
2746 assert(div != NULL);
2747
2748 *nom = 0;
2749 *den = 0;
2750 *div = 0;
2751
2752 if (freq < 8000)
2753 freq = 8000;
2754
2755 diff = freq;
2756
2757 for (n = 32; n < 128; n++) {
2758 int s = 0;
2759
2760 d = (14318 * n) / freq;
2761 if ((d >= 7) && (d <= 63)) {
2762 int temp = d;
2763
2764 if (temp > 31) {
2765 s = 1;
2766 temp >>= 1;
2767 }
2768 h = ((14318 * n) / temp) >> s;
2769 h = h > freq ? h - freq : freq - h;
2770 if (h < diff) {
2771 diff = h;
2772 *nom = n;
2773 *den = temp;
2774 *div = s;
2775 }
2776 }
2777 d++;
2778 if ((d >= 7) && (d <= 63)) {
2779 if (d > 31) {
2780 s = 1;
2781 d >>= 1;
2782 }
2783 h = ((14318 * n) / d) >> s;
2784 h = h > freq ? h - freq : freq - h;
2785 if (h < diff) {
2786 diff = h;
2787 *nom = n;
2788 *den = d;
2789 *div = s;
2790 }
2791 }
2792 }
2793}
2794
2795
2796
2797
2798
2799
2800
2801
2802#ifdef CIRRUSFB_DEBUG
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815static void cirrusfb_dbg_print_regs(struct fb_info *info,
2816 caddr_t regbase,
2817 enum cirrusfb_dbg_reg_class reg_class, ...)
2818{
2819 va_list list;
2820 unsigned char val = 0;
2821 unsigned reg;
2822 char *name;
2823
2824 va_start(list, reg_class);
2825
2826 name = va_arg(list, char *);
2827 while (name != NULL) {
2828 reg = va_arg(list, int);
2829
2830 switch (reg_class) {
2831 case CRT:
2832 val = vga_rcrt(regbase, (unsigned char) reg);
2833 break;
2834 case SEQ:
2835 val = vga_rseq(regbase, (unsigned char) reg);
2836 break;
2837 default:
2838
2839 assert(false);
2840 break;
2841 }
2842
2843 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2844
2845 name = va_arg(list, char *);
2846 }
2847
2848 va_end(list);
2849}
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2862{
2863 dev_dbg(info->device, "VGA CRTC register dump:\n");
2864
2865 cirrusfb_dbg_print_regs(info, regbase, CRT,
2866 "CR00", 0x00,
2867 "CR01", 0x01,
2868 "CR02", 0x02,
2869 "CR03", 0x03,
2870 "CR04", 0x04,
2871 "CR05", 0x05,
2872 "CR06", 0x06,
2873 "CR07", 0x07,
2874 "CR08", 0x08,
2875 "CR09", 0x09,
2876 "CR0A", 0x0A,
2877 "CR0B", 0x0B,
2878 "CR0C", 0x0C,
2879 "CR0D", 0x0D,
2880 "CR0E", 0x0E,
2881 "CR0F", 0x0F,
2882 "CR10", 0x10,
2883 "CR11", 0x11,
2884 "CR12", 0x12,
2885 "CR13", 0x13,
2886 "CR14", 0x14,
2887 "CR15", 0x15,
2888 "CR16", 0x16,
2889 "CR17", 0x17,
2890 "CR18", 0x18,
2891 "CR22", 0x22,
2892 "CR24", 0x24,
2893 "CR26", 0x26,
2894 "CR2D", 0x2D,
2895 "CR2E", 0x2E,
2896 "CR2F", 0x2F,
2897 "CR30", 0x30,
2898 "CR31", 0x31,
2899 "CR32", 0x32,
2900 "CR33", 0x33,
2901 "CR34", 0x34,
2902 "CR35", 0x35,
2903 "CR36", 0x36,
2904 "CR37", 0x37,
2905 "CR38", 0x38,
2906 "CR39", 0x39,
2907 "CR3A", 0x3A,
2908 "CR3B", 0x3B,
2909 "CR3C", 0x3C,
2910 "CR3D", 0x3D,
2911 "CR3E", 0x3E,
2912 "CR3F", 0x3F,
2913 NULL);
2914
2915 dev_dbg(info->device, "\n");
2916
2917 dev_dbg(info->device, "VGA SEQ register dump:\n");
2918
2919 cirrusfb_dbg_print_regs(info, regbase, SEQ,
2920 "SR00", 0x00,
2921 "SR01", 0x01,
2922 "SR02", 0x02,
2923 "SR03", 0x03,
2924 "SR04", 0x04,
2925 "SR08", 0x08,
2926 "SR09", 0x09,
2927 "SR0A", 0x0A,
2928 "SR0B", 0x0B,
2929 "SR0D", 0x0D,
2930 "SR10", 0x10,
2931 "SR11", 0x11,
2932 "SR12", 0x12,
2933 "SR13", 0x13,
2934 "SR14", 0x14,
2935 "SR15", 0x15,
2936 "SR16", 0x16,
2937 "SR17", 0x17,
2938 "SR18", 0x18,
2939 "SR19", 0x19,
2940 "SR1A", 0x1A,
2941 "SR1B", 0x1B,
2942 "SR1C", 0x1C,
2943 "SR1D", 0x1D,
2944 "SR1E", 0x1E,
2945 "SR1F", 0x1F,
2946 NULL);
2947
2948 dev_dbg(info->device, "\n");
2949}
2950
2951#endif
2952
2953