This source file includes following definitions.
- is_laguna
- cirrusfb_open
- cirrusfb_release
- cirrusfb_check_mclk
- cirrusfb_check_pixclock
- cirrusfb_check_var
- cirrusfb_set_mclk_as_source
- cirrusfb_set_par_foo
- cirrusfb_set_par
- cirrusfb_setcolreg
- cirrusfb_pan_display
- cirrusfb_blank
- init_vgachip
- switch_monitor
- cirrusfb_sync
- cirrusfb_fillrect
- cirrusfb_copyarea
- cirrusfb_imageblit
- cirrusfb_get_memsize
- get_pci_addrs
- cirrusfb_pci_unmap
- cirrusfb_zorro_unmap
- cirrusfb_set_fbinfo
- cirrusfb_register
- cirrusfb_cleanup
- cirrusfb_pci_register
- cirrusfb_pci_unregister
- cirrusfb_zorro_register
- cirrusfb_zorro_unregister
- cirrusfb_setup
- cirrusfb_init
- cirrusfb_exit
- WGen
- RGen
- AttrOn
- WHDR
- WSFR
- WSFR2
- WClut
- RClut
- cirrusfb_WaitBLT
- cirrusfb_set_blitter
- cirrusfb_BitBLT
- cirrusfb_RectFill
- bestclock
- cirrusfb_dbg_print_regs
- cirrusfb_dbg_reg_dump
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
89 enum 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
111 static 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
258 static struct pci_device_id cirrusfb_pci_table[] = {
259 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
260 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
261 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
262 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE),
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 };
272 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
273 #undef CHIP
274 #endif
275
276 #ifdef CONFIG_ZORRO
277 struct 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
287 static const struct zorrocl zcl_sd64 = {
288 .type = BT_SD64,
289 .ramid = ZORRO_PROD_HELFRICH_SD64_RAM,
290 };
291
292 static const struct zorrocl zcl_piccolo = {
293 .type = BT_PICCOLO,
294 .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
295 };
296
297 static const struct zorrocl zcl_picasso = {
298 .type = BT_PICASSO,
299 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
300 };
301
302 static const struct zorrocl zcl_spectrum = {
303 .type = BT_SPECTRUM,
304 .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
305 };
306
307 static const struct zorrocl zcl_picasso4_z3 = {
308 .type = BT_PICASSO4,
309 .regoffset = 0x00600000,
310 .ramsize = 4 * MB_,
311 .ramoffset = 0x01000000,
312 };
313
314 static const struct zorrocl zcl_picasso4_z2 = {
315 .type = BT_PICASSO4,
316 .regoffset = 0x10000,
317 .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
318 .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
319 };
320
321
322 static 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 };
344 MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
345 #endif
346
347 #ifdef CIRRUSFB_DEBUG
348 enum cirrusfb_dbg_reg_class {
349 CRT,
350 SEQ
351 };
352 #endif
353
354
355 struct 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
369 static bool noaccel;
370 static char *mode_option = "640x480@60";
371
372
373
374
375
376 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
377 struct fb_info *info);
378
379
380 static void init_vgachip(struct fb_info *info);
381 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
382 static void WGen(const struct cirrusfb_info *cinfo,
383 int regnum, unsigned char val);
384 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
385 static void AttrOn(const struct cirrusfb_info *cinfo);
386 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
387 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
388 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
389 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
390 unsigned char red, unsigned char green, unsigned char blue);
391 #if 0
392 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
393 unsigned char *red, unsigned char *green,
394 unsigned char *blue);
395 #endif
396 static void cirrusfb_WaitBLT(u8 __iomem *regbase);
397 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
398 u_short curx, u_short cury,
399 u_short destx, u_short desty,
400 u_short width, u_short height,
401 u_short line_length);
402 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
403 u_short x, u_short y,
404 u_short width, u_short height,
405 u32 fg_color, u32 bg_color,
406 u_short line_length, u_char blitmode);
407
408 static void bestclock(long freq, int *nom, int *den, int *div);
409
410 #ifdef CIRRUSFB_DEBUG
411 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
412 static void cirrusfb_dbg_print_regs(struct fb_info *info,
413 caddr_t regbase,
414 enum cirrusfb_dbg_reg_class reg_class, ...);
415 #endif
416
417
418
419
420
421 static inline int is_laguna(const struct cirrusfb_info *cinfo)
422 {
423 return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
424 }
425
426 static int opencount;
427
428
429 static 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
437 static 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
449 static 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
473 static 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
530 static 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
632 static 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
658 static 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
1270 static int cirrusfb_set_par(struct fb_info *info)
1271 {
1272 cirrusfb_set_par_foo(info);
1273 return cirrusfb_set_par_foo(info);
1274 }
1275
1276 static 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
1313 static 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
1377 static 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
1446 static 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
1481 case BT_GD5480:
1482
1483 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1484
1485 case BT_ALPINE:
1486
1487 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1488 break;
1489
1490 case BT_LAGUNA:
1491 case BT_LAGUNAB:
1492
1493 break;
1494
1495 default:
1496 dev_err(info->device, "Warning: Unknown board type\n");
1497 break;
1498 }
1499
1500
1501 assert(info->screen_size > 0);
1502
1503
1504
1505
1506
1507 if (cinfo->btype != BT_PICASSO4) {
1508 WGen(cinfo, CL_VSSM, 0x10);
1509 WGen(cinfo, CL_POS102, 0x01);
1510 WGen(cinfo, CL_VSSM, 0x08);
1511
1512 if (cinfo->btype != BT_SD64)
1513 WGen(cinfo, CL_VSSM2, 0x01);
1514
1515
1516 vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
1517
1518
1519 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1520
1521
1522
1523
1524 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1525
1526 switch (cinfo->btype) {
1527 case BT_GD5480:
1528 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1529 break;
1530 case BT_ALPINE:
1531 case BT_LAGUNA:
1532 case BT_LAGUNAB:
1533 break;
1534 case BT_SD64:
1535 #ifdef CONFIG_ZORRO
1536 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1537 #endif
1538 break;
1539 default:
1540 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1541 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1542 break;
1543 }
1544 }
1545
1546 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1547
1548 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1549
1550 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1551
1552
1553 if (bi->init_sr07)
1554 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1555
1556
1557
1558
1559
1560 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1561
1562 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1563
1564 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1565
1566 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1567
1568
1569 if (cinfo->btype != BT_PICASSO4) {
1570
1571 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1572
1573 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1574 }
1575
1576
1577 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1578
1579 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1580
1581 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1582
1583 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1584
1585 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1586
1587
1588 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1589
1590
1591 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1592
1593
1594 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1595
1596 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1597
1598 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1599
1600 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1601
1602 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1603
1604 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1605
1606 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1607
1608 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1609
1610 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1611
1612 if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
1613 is_laguna(cinfo))
1614
1615 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1616 else
1617
1618
1619
1620 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1621
1622 vga_wgfx(cinfo->regbase, CL_GRC, 0xff);
1623 vga_wgfx(cinfo->regbase, CL_GRD, 0x00);
1624 vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
1625
1626
1627
1628
1629
1630 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1631 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1632 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1633 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1634 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1635 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1636 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1637 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1638 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1639 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1640 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1641 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1642 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1643 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1644 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1645 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1646
1647
1648 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1649
1650 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1651
1652 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1653
1654 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1655
1656 WGen(cinfo, VGA_PEL_MSK, 0xff);
1657
1658
1659 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1660
1661 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1662
1663
1664 WHDR(cinfo, 0);
1665 return;
1666 }
1667
1668 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1669 {
1670 #ifdef CONFIG_ZORRO
1671 static int IsOn = 0;
1672
1673 if (cinfo->btype == BT_PICASSO4)
1674 return;
1675 if (cinfo->btype == BT_ALPINE)
1676 return;
1677 if (cinfo->btype == BT_GD5480)
1678 return;
1679 if (cinfo->btype == BT_PICASSO) {
1680 if ((on && !IsOn) || (!on && IsOn))
1681 WSFR(cinfo, 0xff);
1682 return;
1683 }
1684 if (on) {
1685 switch (cinfo->btype) {
1686 case BT_SD64:
1687 WSFR(cinfo, cinfo->SFR | 0x21);
1688 break;
1689 case BT_PICCOLO:
1690 WSFR(cinfo, cinfo->SFR | 0x28);
1691 break;
1692 case BT_SPECTRUM:
1693 WSFR(cinfo, 0x6f);
1694 break;
1695 default: break;
1696 }
1697 } else {
1698 switch (cinfo->btype) {
1699 case BT_SD64:
1700 WSFR(cinfo, cinfo->SFR & 0xde);
1701 break;
1702 case BT_PICCOLO:
1703 WSFR(cinfo, cinfo->SFR & 0xd7);
1704 break;
1705 case BT_SPECTRUM:
1706 WSFR(cinfo, 0x4f);
1707 break;
1708 default:
1709 break;
1710 }
1711 }
1712 #endif
1713 }
1714
1715
1716
1717
1718
1719 static int cirrusfb_sync(struct fb_info *info)
1720 {
1721 struct cirrusfb_info *cinfo = info->par;
1722
1723 if (!is_laguna(cinfo)) {
1724 while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
1725 cpu_relax();
1726 }
1727 return 0;
1728 }
1729
1730 static void cirrusfb_fillrect(struct fb_info *info,
1731 const struct fb_fillrect *region)
1732 {
1733 struct fb_fillrect modded;
1734 int vxres, vyres;
1735 struct cirrusfb_info *cinfo = info->par;
1736 int m = info->var.bits_per_pixel;
1737 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1738 cinfo->pseudo_palette[region->color] : region->color;
1739
1740 if (info->state != FBINFO_STATE_RUNNING)
1741 return;
1742 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1743 cfb_fillrect(info, region);
1744 return;
1745 }
1746
1747 vxres = info->var.xres_virtual;
1748 vyres = info->var.yres_virtual;
1749
1750 memcpy(&modded, region, sizeof(struct fb_fillrect));
1751
1752 if (!modded.width || !modded.height ||
1753 modded.dx >= vxres || modded.dy >= vyres)
1754 return;
1755
1756 if (modded.dx + modded.width > vxres)
1757 modded.width = vxres - modded.dx;
1758 if (modded.dy + modded.height > vyres)
1759 modded.height = vyres - modded.dy;
1760
1761 cirrusfb_RectFill(cinfo->regbase,
1762 info->var.bits_per_pixel,
1763 (region->dx * m) / 8, region->dy,
1764 (region->width * m) / 8, region->height,
1765 color, color,
1766 info->fix.line_length, 0x40);
1767 }
1768
1769 static void cirrusfb_copyarea(struct fb_info *info,
1770 const struct fb_copyarea *area)
1771 {
1772 struct fb_copyarea modded;
1773 u32 vxres, vyres;
1774 struct cirrusfb_info *cinfo = info->par;
1775 int m = info->var.bits_per_pixel;
1776
1777 if (info->state != FBINFO_STATE_RUNNING)
1778 return;
1779 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1780 cfb_copyarea(info, area);
1781 return;
1782 }
1783
1784 vxres = info->var.xres_virtual;
1785 vyres = info->var.yres_virtual;
1786 memcpy(&modded, area, sizeof(struct fb_copyarea));
1787
1788 if (!modded.width || !modded.height ||
1789 modded.sx >= vxres || modded.sy >= vyres ||
1790 modded.dx >= vxres || modded.dy >= vyres)
1791 return;
1792
1793 if (modded.sx + modded.width > vxres)
1794 modded.width = vxres - modded.sx;
1795 if (modded.dx + modded.width > vxres)
1796 modded.width = vxres - modded.dx;
1797 if (modded.sy + modded.height > vyres)
1798 modded.height = vyres - modded.sy;
1799 if (modded.dy + modded.height > vyres)
1800 modded.height = vyres - modded.dy;
1801
1802 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1803 (area->sx * m) / 8, area->sy,
1804 (area->dx * m) / 8, area->dy,
1805 (area->width * m) / 8, area->height,
1806 info->fix.line_length);
1807
1808 }
1809
1810 static void cirrusfb_imageblit(struct fb_info *info,
1811 const struct fb_image *image)
1812 {
1813 struct cirrusfb_info *cinfo = info->par;
1814 unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
1815
1816 if (info->state != FBINFO_STATE_RUNNING)
1817 return;
1818
1819 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
1820 cfb_imageblit(info, image);
1821 else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
1822 op == 0xc)
1823 cfb_imageblit(info, image);
1824 else {
1825 unsigned size = ((image->width + 7) >> 3) * image->height;
1826 int m = info->var.bits_per_pixel;
1827 u32 fg, bg;
1828
1829 if (info->var.bits_per_pixel == 8) {
1830 fg = image->fg_color;
1831 bg = image->bg_color;
1832 } else {
1833 fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
1834 bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
1835 }
1836 if (info->var.bits_per_pixel == 24) {
1837
1838 cirrusfb_RectFill(cinfo->regbase,
1839 info->var.bits_per_pixel,
1840 (image->dx * m) / 8, image->dy,
1841 (image->width * m) / 8,
1842 image->height,
1843 bg, bg,
1844 info->fix.line_length, 0x40);
1845 }
1846 cirrusfb_RectFill(cinfo->regbase,
1847 info->var.bits_per_pixel,
1848 (image->dx * m) / 8, image->dy,
1849 (image->width * m) / 8, image->height,
1850 fg, bg,
1851 info->fix.line_length, op);
1852 memcpy(info->screen_base, image->data, size);
1853 }
1854 }
1855
1856 #ifdef CONFIG_PCI
1857 static int release_io_ports;
1858
1859
1860
1861
1862
1863 static unsigned int cirrusfb_get_memsize(struct fb_info *info,
1864 u8 __iomem *regbase)
1865 {
1866 unsigned long mem;
1867 struct cirrusfb_info *cinfo = info->par;
1868
1869 if (is_laguna(cinfo)) {
1870 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1871
1872 mem = ((SR14 & 7) + 1) << 20;
1873 } else {
1874 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1875 switch ((SRF & 0x18)) {
1876 case 0x08:
1877 mem = 512 * 1024;
1878 break;
1879 case 0x10:
1880 mem = 1024 * 1024;
1881 break;
1882
1883
1884
1885 case 0x18:
1886 mem = 2048 * 1024;
1887 break;
1888 default:
1889 dev_warn(info->device, "Unknown memory size!\n");
1890 mem = 1024 * 1024;
1891 }
1892
1893
1894
1895 if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
1896 mem *= 2;
1897 }
1898
1899
1900 return mem;
1901 }
1902
1903 static void get_pci_addrs(const struct pci_dev *pdev,
1904 unsigned long *display, unsigned long *registers)
1905 {
1906 assert(pdev != NULL);
1907 assert(display != NULL);
1908 assert(registers != NULL);
1909
1910 *display = 0;
1911 *registers = 0;
1912
1913
1914
1915 if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1916 *display = pci_resource_start(pdev, 1);
1917 *registers = pci_resource_start(pdev, 0);
1918 } else {
1919 *display = pci_resource_start(pdev, 0);
1920 *registers = pci_resource_start(pdev, 1);
1921 }
1922
1923 assert(*display != 0);
1924 }
1925
1926 static void cirrusfb_pci_unmap(struct fb_info *info)
1927 {
1928 struct pci_dev *pdev = to_pci_dev(info->device);
1929 struct cirrusfb_info *cinfo = info->par;
1930
1931 if (cinfo->laguna_mmio == NULL)
1932 iounmap(cinfo->laguna_mmio);
1933 iounmap(info->screen_base);
1934 #if 0
1935 release_mem_region(0xA0000, 65535);
1936 #endif
1937 if (release_io_ports)
1938 release_region(0x3C0, 32);
1939 pci_release_regions(pdev);
1940 }
1941 #endif
1942
1943 #ifdef CONFIG_ZORRO
1944 static void cirrusfb_zorro_unmap(struct fb_info *info)
1945 {
1946 struct cirrusfb_info *cinfo = info->par;
1947 struct zorro_dev *zdev = to_zorro_dev(info->device);
1948
1949 if (info->fix.smem_start > 16 * MB_)
1950 iounmap(info->screen_base);
1951 if (info->fix.mmio_start > 16 * MB_)
1952 iounmap(cinfo->regbase);
1953
1954 zorro_release_device(zdev);
1955 }
1956 #endif
1957
1958
1959 static struct fb_ops cirrusfb_ops = {
1960 .owner = THIS_MODULE,
1961 .fb_open = cirrusfb_open,
1962 .fb_release = cirrusfb_release,
1963 .fb_setcolreg = cirrusfb_setcolreg,
1964 .fb_check_var = cirrusfb_check_var,
1965 .fb_set_par = cirrusfb_set_par,
1966 .fb_pan_display = cirrusfb_pan_display,
1967 .fb_blank = cirrusfb_blank,
1968 .fb_fillrect = cirrusfb_fillrect,
1969 .fb_copyarea = cirrusfb_copyarea,
1970 .fb_sync = cirrusfb_sync,
1971 .fb_imageblit = cirrusfb_imageblit,
1972 };
1973
1974 static int cirrusfb_set_fbinfo(struct fb_info *info)
1975 {
1976 struct cirrusfb_info *cinfo = info->par;
1977 struct fb_var_screeninfo *var = &info->var;
1978
1979 info->pseudo_palette = cinfo->pseudo_palette;
1980 info->flags = FBINFO_DEFAULT
1981 | FBINFO_HWACCEL_XPAN
1982 | FBINFO_HWACCEL_YPAN
1983 | FBINFO_HWACCEL_FILLRECT
1984 | FBINFO_HWACCEL_IMAGEBLIT
1985 | FBINFO_HWACCEL_COPYAREA;
1986 if (noaccel || is_laguna(cinfo)) {
1987 info->flags |= FBINFO_HWACCEL_DISABLED;
1988 info->fix.accel = FB_ACCEL_NONE;
1989 } else
1990 info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
1991
1992 info->fbops = &cirrusfb_ops;
1993
1994 if (cinfo->btype == BT_GD5480) {
1995 if (var->bits_per_pixel == 16)
1996 info->screen_base += 1 * MB_;
1997 if (var->bits_per_pixel == 32)
1998 info->screen_base += 2 * MB_;
1999 }
2000
2001
2002 strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2003 sizeof(info->fix.id));
2004
2005
2006
2007 info->fix.smem_len = info->screen_size;
2008 if (var->bits_per_pixel == 1)
2009 info->fix.smem_len /= 4;
2010 info->fix.type_aux = 0;
2011 info->fix.xpanstep = 1;
2012 info->fix.ypanstep = 1;
2013 info->fix.ywrapstep = 0;
2014
2015
2016 info->fix.mmio_len = 0;
2017
2018 fb_alloc_cmap(&info->cmap, 256, 0);
2019
2020 return 0;
2021 }
2022
2023 static int cirrusfb_register(struct fb_info *info)
2024 {
2025 struct cirrusfb_info *cinfo = info->par;
2026 int err;
2027
2028
2029 assert(cinfo->btype != BT_NONE);
2030
2031
2032 cirrusfb_set_fbinfo(info);
2033
2034 dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2035
2036 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2037 if (!err) {
2038 dev_dbg(info->device, "wrong initial video mode\n");
2039 err = -EINVAL;
2040 goto err_dealloc_cmap;
2041 }
2042
2043 info->var.activate = FB_ACTIVATE_NOW;
2044
2045 err = cirrusfb_check_var(&info->var, info);
2046 if (err < 0) {
2047
2048 dev_dbg(info->device,
2049 "choking on default var... umm, no good.\n");
2050 goto err_dealloc_cmap;
2051 }
2052
2053 err = register_framebuffer(info);
2054 if (err < 0) {
2055 dev_err(info->device,
2056 "could not register fb device; err = %d!\n", err);
2057 goto err_dealloc_cmap;
2058 }
2059
2060 return 0;
2061
2062 err_dealloc_cmap:
2063 fb_dealloc_cmap(&info->cmap);
2064 return err;
2065 }
2066
2067 static void cirrusfb_cleanup(struct fb_info *info)
2068 {
2069 struct cirrusfb_info *cinfo = info->par;
2070
2071 switch_monitor(cinfo, 0);
2072 unregister_framebuffer(info);
2073 fb_dealloc_cmap(&info->cmap);
2074 dev_dbg(info->device, "Framebuffer unregistered\n");
2075 cinfo->unmap(info);
2076 framebuffer_release(info);
2077 }
2078
2079 #ifdef CONFIG_PCI
2080 static int cirrusfb_pci_register(struct pci_dev *pdev,
2081 const struct pci_device_id *ent)
2082 {
2083 struct cirrusfb_info *cinfo;
2084 struct fb_info *info;
2085 unsigned long board_addr, board_size;
2086 int ret;
2087
2088 ret = pci_enable_device(pdev);
2089 if (ret < 0) {
2090 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2091 goto err_out;
2092 }
2093
2094 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2095 if (!info) {
2096 ret = -ENOMEM;
2097 goto err_out;
2098 }
2099
2100 cinfo = info->par;
2101 cinfo->btype = (enum cirrus_board) ent->driver_data;
2102
2103 dev_dbg(info->device,
2104 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2105 (unsigned long long)pdev->resource[0].start, cinfo->btype);
2106 dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2107 (unsigned long long)pdev->resource[1].start);
2108
2109 dev_dbg(info->device,
2110 "Attempt to get PCI info for Cirrus Graphics Card\n");
2111 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2112
2113 cinfo->regbase = NULL;
2114 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2115
2116 dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2117 board_addr, info->fix.mmio_start);
2118
2119 board_size = (cinfo->btype == BT_GD5480) ?
2120 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2121
2122 ret = pci_request_regions(pdev, "cirrusfb");
2123 if (ret < 0) {
2124 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2125 board_addr);
2126 goto err_release_fb;
2127 }
2128 #if 0
2129 if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2130 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2131 0xA0000L);
2132 ret = -EBUSY;
2133 goto err_release_regions;
2134 }
2135 #endif
2136 if (request_region(0x3C0, 32, "cirrusfb"))
2137 release_io_ports = 1;
2138
2139 info->screen_base = ioremap(board_addr, board_size);
2140 if (!info->screen_base) {
2141 ret = -EIO;
2142 goto err_release_legacy;
2143 }
2144
2145 info->fix.smem_start = board_addr;
2146 info->screen_size = board_size;
2147 cinfo->unmap = cirrusfb_pci_unmap;
2148
2149 dev_info(info->device,
2150 "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2151 info->screen_size >> 10, board_addr);
2152 pci_set_drvdata(pdev, info);
2153
2154 ret = cirrusfb_register(info);
2155 if (!ret)
2156 return 0;
2157
2158 iounmap(info->screen_base);
2159 err_release_legacy:
2160 if (release_io_ports)
2161 release_region(0x3C0, 32);
2162 #if 0
2163 release_mem_region(0xA0000, 65535);
2164 err_release_regions:
2165 #endif
2166 pci_release_regions(pdev);
2167 err_release_fb:
2168 if (cinfo->laguna_mmio != NULL)
2169 iounmap(cinfo->laguna_mmio);
2170 framebuffer_release(info);
2171 err_out:
2172 return ret;
2173 }
2174
2175 static void cirrusfb_pci_unregister(struct pci_dev *pdev)
2176 {
2177 struct fb_info *info = pci_get_drvdata(pdev);
2178
2179 cirrusfb_cleanup(info);
2180 }
2181
2182 static struct pci_driver cirrusfb_pci_driver = {
2183 .name = "cirrusfb",
2184 .id_table = cirrusfb_pci_table,
2185 .probe = cirrusfb_pci_register,
2186 .remove = cirrusfb_pci_unregister,
2187 #ifdef CONFIG_PM
2188 #if 0
2189 .suspend = cirrusfb_pci_suspend,
2190 .resume = cirrusfb_pci_resume,
2191 #endif
2192 #endif
2193 };
2194 #endif
2195
2196 #ifdef CONFIG_ZORRO
2197 static int cirrusfb_zorro_register(struct zorro_dev *z,
2198 const struct zorro_device_id *ent)
2199 {
2200 struct fb_info *info;
2201 int error;
2202 const struct zorrocl *zcl;
2203 enum cirrus_board btype;
2204 unsigned long regbase, ramsize, rambase;
2205 struct cirrusfb_info *cinfo;
2206
2207 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2208 if (!info)
2209 return -ENOMEM;
2210
2211 zcl = (const struct zorrocl *)ent->driver_data;
2212 btype = zcl->type;
2213 regbase = zorro_resource_start(z) + zcl->regoffset;
2214 ramsize = zcl->ramsize;
2215 if (ramsize) {
2216 rambase = zorro_resource_start(z) + zcl->ramoffset;
2217 if (zorro_resource_len(z) == 64 * MB_) {
2218
2219 rambase += zcl->ramoffset;
2220 }
2221 } else {
2222 struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2223 if (!ram || !zorro_resource_len(ram)) {
2224 dev_err(info->device, "No video RAM found\n");
2225 error = -ENODEV;
2226 goto err_release_fb;
2227 }
2228 rambase = zorro_resource_start(ram);
2229 ramsize = zorro_resource_len(ram);
2230 if (zcl->ramid2 &&
2231 (ram = zorro_find_device(zcl->ramid2, NULL))) {
2232 if (zorro_resource_start(ram) != rambase + ramsize) {
2233 dev_warn(info->device,
2234 "Skipping non-contiguous RAM at %pR\n",
2235 &ram->resource);
2236 } else {
2237 ramsize += zorro_resource_len(ram);
2238 }
2239 }
2240 }
2241
2242 dev_info(info->device,
2243 "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2244 cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2245 rambase);
2246
2247 if (!zorro_request_device(z, "cirrusfb")) {
2248 dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2249 error = -EBUSY;
2250 goto err_release_fb;
2251 }
2252
2253 cinfo = info->par;
2254 cinfo->btype = btype;
2255
2256 info->fix.mmio_start = regbase;
2257 cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2258 : ZTWO_VADDR(regbase);
2259 if (!cinfo->regbase) {
2260 dev_err(info->device, "Cannot map registers\n");
2261 error = -EIO;
2262 goto err_release_dev;
2263 }
2264
2265 info->fix.smem_start = rambase;
2266 info->screen_size = ramsize;
2267 info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2268 : ZTWO_VADDR(rambase);
2269 if (!info->screen_base) {
2270 dev_err(info->device, "Cannot map video RAM\n");
2271 error = -EIO;
2272 goto err_unmap_reg;
2273 }
2274
2275 cinfo->unmap = cirrusfb_zorro_unmap;
2276
2277 dev_info(info->device,
2278 "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2279 ramsize / MB_, rambase);
2280
2281
2282 if (cirrusfb_board_info[btype].init_sr1f)
2283 vga_wseq(cinfo->regbase, CL_SEQR1F,
2284 cirrusfb_board_info[btype].sr1f);
2285
2286 error = cirrusfb_register(info);
2287 if (error) {
2288 dev_err(info->device, "Failed to register device, error %d\n",
2289 error);
2290 goto err_unmap_ram;
2291 }
2292
2293 zorro_set_drvdata(z, info);
2294 return 0;
2295
2296 err_unmap_ram:
2297 if (rambase > 16 * MB_)
2298 iounmap(info->screen_base);
2299
2300 err_unmap_reg:
2301 if (regbase > 16 * MB_)
2302 iounmap(cinfo->regbase);
2303 err_release_dev:
2304 zorro_release_device(z);
2305 err_release_fb:
2306 framebuffer_release(info);
2307 return error;
2308 }
2309
2310 void cirrusfb_zorro_unregister(struct zorro_dev *z)
2311 {
2312 struct fb_info *info = zorro_get_drvdata(z);
2313
2314 cirrusfb_cleanup(info);
2315 zorro_set_drvdata(z, NULL);
2316 }
2317
2318 static struct zorro_driver cirrusfb_zorro_driver = {
2319 .name = "cirrusfb",
2320 .id_table = cirrusfb_zorro_table,
2321 .probe = cirrusfb_zorro_register,
2322 .remove = cirrusfb_zorro_unregister,
2323 };
2324 #endif
2325
2326 #ifndef MODULE
2327 static int __init cirrusfb_setup(char *options)
2328 {
2329 char *this_opt;
2330
2331 if (!options || !*options)
2332 return 0;
2333
2334 while ((this_opt = strsep(&options, ",")) != NULL) {
2335 if (!*this_opt)
2336 continue;
2337
2338 if (!strcmp(this_opt, "noaccel"))
2339 noaccel = 1;
2340 else if (!strncmp(this_opt, "mode:", 5))
2341 mode_option = this_opt + 5;
2342 else
2343 mode_option = this_opt;
2344 }
2345 return 0;
2346 }
2347 #endif
2348
2349
2350
2351
2352
2353 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2354 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2355 MODULE_LICENSE("GPL");
2356
2357 static int __init cirrusfb_init(void)
2358 {
2359 int error = 0;
2360
2361 #ifndef MODULE
2362 char *option = NULL;
2363
2364 if (fb_get_options("cirrusfb", &option))
2365 return -ENODEV;
2366 cirrusfb_setup(option);
2367 #endif
2368
2369 #ifdef CONFIG_ZORRO
2370 error |= zorro_register_driver(&cirrusfb_zorro_driver);
2371 #endif
2372 #ifdef CONFIG_PCI
2373 error |= pci_register_driver(&cirrusfb_pci_driver);
2374 #endif
2375 return error;
2376 }
2377
2378 static void __exit cirrusfb_exit(void)
2379 {
2380 #ifdef CONFIG_PCI
2381 pci_unregister_driver(&cirrusfb_pci_driver);
2382 #endif
2383 #ifdef CONFIG_ZORRO
2384 zorro_unregister_driver(&cirrusfb_zorro_driver);
2385 #endif
2386 }
2387
2388 module_init(cirrusfb_init);
2389
2390 module_param(mode_option, charp, 0);
2391 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2392 module_param(noaccel, bool, 0);
2393 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2394
2395 #ifdef MODULE
2396 module_exit(cirrusfb_exit);
2397 #endif
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407 static void WGen(const struct cirrusfb_info *cinfo,
2408 int regnum, unsigned char val)
2409 {
2410 unsigned long regofs = 0;
2411
2412 if (cinfo->btype == BT_PICASSO) {
2413
2414
2415
2416 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2417 regofs = 0xfff;
2418 }
2419
2420 vga_w(cinfo->regbase, regofs + regnum, val);
2421 }
2422
2423
2424 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2425 {
2426 unsigned long regofs = 0;
2427
2428 if (cinfo->btype == BT_PICASSO) {
2429
2430
2431
2432 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2433 regofs = 0xfff;
2434 }
2435
2436 return vga_r(cinfo->regbase, regofs + regnum);
2437 }
2438
2439
2440 static void AttrOn(const struct cirrusfb_info *cinfo)
2441 {
2442 assert(cinfo != NULL);
2443
2444 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2445
2446
2447 vga_w(cinfo->regbase, VGA_ATT_IW,
2448 vga_r(cinfo->regbase, VGA_ATT_R));
2449 }
2450
2451
2452 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2453
2454
2455 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2456 }
2457
2458
2459
2460
2461
2462
2463
2464 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2465 {
2466 unsigned char dummy;
2467
2468 if (is_laguna(cinfo))
2469 return;
2470 if (cinfo->btype == BT_PICASSO) {
2471
2472
2473 WGen(cinfo, VGA_PEL_MSK, 0x00);
2474 udelay(200);
2475
2476 dummy = RGen(cinfo, VGA_PEL_IW);
2477 udelay(200);
2478 }
2479
2480
2481 dummy = RGen(cinfo, VGA_PEL_MSK);
2482 udelay(200);
2483 dummy = RGen(cinfo, VGA_PEL_MSK);
2484 udelay(200);
2485 dummy = RGen(cinfo, VGA_PEL_MSK);
2486 udelay(200);
2487 dummy = RGen(cinfo, VGA_PEL_MSK);
2488 udelay(200);
2489
2490 WGen(cinfo, VGA_PEL_MSK, val);
2491 udelay(200);
2492
2493 if (cinfo->btype == BT_PICASSO) {
2494
2495 dummy = RGen(cinfo, VGA_PEL_IW);
2496 udelay(200);
2497
2498
2499
2500 WGen(cinfo, VGA_PEL_MSK, 0xff);
2501 udelay(200);
2502 }
2503 }
2504
2505
2506 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2507 {
2508 #ifdef CONFIG_ZORRO
2509 assert(cinfo->regbase != NULL);
2510 cinfo->SFR = val;
2511 z_writeb(val, cinfo->regbase + 0x8000);
2512 #endif
2513 }
2514
2515
2516 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2517 {
2518 #ifdef CONFIG_ZORRO
2519
2520
2521 assert(cinfo->regbase != NULL);
2522 cinfo->SFR = val;
2523 z_writeb(val, cinfo->regbase + 0x9000);
2524 #endif
2525 }
2526
2527
2528 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2529 unsigned char green, unsigned char blue)
2530 {
2531 unsigned int data = VGA_PEL_D;
2532
2533
2534 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2535
2536 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2537 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2538 cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2539
2540 if (cinfo->btype == BT_PICASSO)
2541 data += 0xfff;
2542 vga_w(cinfo->regbase, data, red);
2543 vga_w(cinfo->regbase, data, green);
2544 vga_w(cinfo->regbase, data, blue);
2545 } else {
2546 vga_w(cinfo->regbase, data, blue);
2547 vga_w(cinfo->regbase, data, green);
2548 vga_w(cinfo->regbase, data, red);
2549 }
2550 }
2551
2552 #if 0
2553
2554 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2555 unsigned char *green, unsigned char *blue)
2556 {
2557 unsigned int data = VGA_PEL_D;
2558
2559 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2560
2561 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2562 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2563 if (cinfo->btype == BT_PICASSO)
2564 data += 0xfff;
2565 *red = vga_r(cinfo->regbase, data);
2566 *green = vga_r(cinfo->regbase, data);
2567 *blue = vga_r(cinfo->regbase, data);
2568 } else {
2569 *blue = vga_r(cinfo->regbase, data);
2570 *green = vga_r(cinfo->regbase, data);
2571 *red = vga_r(cinfo->regbase, data);
2572 }
2573 }
2574 #endif
2575
2576
2577
2578
2579
2580
2581
2582
2583 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2584 {
2585 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2586 cpu_relax();
2587 }
2588
2589
2590
2591
2592
2593
2594
2595 static void cirrusfb_set_blitter(u8 __iomem *regbase,
2596 u_short nwidth, u_short nheight,
2597 u_long nsrc, u_long ndest,
2598 u_short bltmode, u_short line_length)
2599
2600 {
2601
2602
2603 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2604
2605 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2606
2607 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2608
2609 vga_wgfx(regbase, CL_GR27, line_length >> 8);
2610
2611
2612
2613 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2614
2615 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2616
2617
2618
2619 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2620
2621 vga_wgfx(regbase, CL_GR23, nheight >> 8);
2622
2623
2624
2625 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2626
2627 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2628
2629 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2630
2631
2632
2633 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2634
2635 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2636
2637 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2638
2639
2640 vga_wgfx(regbase, CL_GR30, bltmode);
2641
2642
2643 vga_wgfx(regbase, CL_GR32, 0x0d);
2644
2645
2646 vga_wgfx(regbase, CL_GR31, 0x02);
2647 }
2648
2649
2650
2651
2652
2653
2654
2655 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2656 u_short curx, u_short cury,
2657 u_short destx, u_short desty,
2658 u_short width, u_short height,
2659 u_short line_length)
2660 {
2661 u_short nwidth = width - 1;
2662 u_short nheight = height - 1;
2663 u_long nsrc, ndest;
2664 u_char bltmode;
2665
2666 bltmode = 0x00;
2667
2668 if (cury <= desty) {
2669 if (cury == desty) {
2670
2671 if (curx < destx)
2672 bltmode |= 0x01;
2673 } else
2674 bltmode |= 0x01;
2675 }
2676
2677 nsrc = (cury * line_length) + curx;
2678 ndest = (desty * line_length) + destx;
2679 if (bltmode) {
2680
2681
2682
2683 nsrc += nheight * line_length + nwidth;
2684 ndest += nheight * line_length + nwidth;
2685 }
2686
2687 cirrusfb_WaitBLT(regbase);
2688
2689 cirrusfb_set_blitter(regbase, nwidth, nheight,
2690 nsrc, ndest, bltmode, line_length);
2691 }
2692
2693
2694
2695
2696
2697
2698
2699 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2700 u_short x, u_short y, u_short width, u_short height,
2701 u32 fg_color, u32 bg_color, u_short line_length,
2702 u_char blitmode)
2703 {
2704 u_long ndest = (y * line_length) + x;
2705 u_char op;
2706
2707 cirrusfb_WaitBLT(regbase);
2708
2709
2710
2711 vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2712 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2713
2714 op = 0x80;
2715 if (bits_per_pixel >= 16) {
2716 vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2717 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2718 op = 0x90;
2719 }
2720 if (bits_per_pixel >= 24) {
2721 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2722 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2723 op = 0xa0;
2724 }
2725 if (bits_per_pixel == 32) {
2726 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2727 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2728 op = 0xb0;
2729 }
2730 cirrusfb_set_blitter(regbase, width - 1, height - 1,
2731 0, ndest, op | blitmode, line_length);
2732 }
2733
2734
2735
2736
2737
2738 static void bestclock(long freq, int *nom, int *den, int *div)
2739 {
2740 int n, d;
2741 long h, diff;
2742
2743 assert(nom != NULL);
2744 assert(den != NULL);
2745 assert(div != NULL);
2746
2747 *nom = 0;
2748 *den = 0;
2749 *div = 0;
2750
2751 if (freq < 8000)
2752 freq = 8000;
2753
2754 diff = freq;
2755
2756 for (n = 32; n < 128; n++) {
2757 int s = 0;
2758
2759 d = (14318 * n) / freq;
2760 if ((d >= 7) && (d <= 63)) {
2761 int temp = d;
2762
2763 if (temp > 31) {
2764 s = 1;
2765 temp >>= 1;
2766 }
2767 h = ((14318 * n) / temp) >> s;
2768 h = h > freq ? h - freq : freq - h;
2769 if (h < diff) {
2770 diff = h;
2771 *nom = n;
2772 *den = temp;
2773 *div = s;
2774 }
2775 }
2776 d++;
2777 if ((d >= 7) && (d <= 63)) {
2778 if (d > 31) {
2779 s = 1;
2780 d >>= 1;
2781 }
2782 h = ((14318 * n) / d) >> s;
2783 h = h > freq ? h - freq : freq - h;
2784 if (h < diff) {
2785 diff = h;
2786 *nom = n;
2787 *den = d;
2788 *div = s;
2789 }
2790 }
2791 }
2792 }
2793
2794
2795
2796
2797
2798
2799
2800
2801 #ifdef CIRRUSFB_DEBUG
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2815 caddr_t regbase,
2816 enum cirrusfb_dbg_reg_class reg_class, ...)
2817 {
2818 va_list list;
2819 unsigned char val = 0;
2820 unsigned reg;
2821 char *name;
2822
2823 va_start(list, reg_class);
2824
2825 name = va_arg(list, char *);
2826 while (name != NULL) {
2827 reg = va_arg(list, int);
2828
2829 switch (reg_class) {
2830 case CRT:
2831 val = vga_rcrt(regbase, (unsigned char) reg);
2832 break;
2833 case SEQ:
2834 val = vga_rseq(regbase, (unsigned char) reg);
2835 break;
2836 default:
2837
2838 assert(false);
2839 break;
2840 }
2841
2842 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2843
2844 name = va_arg(list, char *);
2845 }
2846
2847 va_end(list);
2848 }
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2861 {
2862 dev_dbg(info->device, "VGA CRTC register dump:\n");
2863
2864 cirrusfb_dbg_print_regs(info, regbase, CRT,
2865 "CR00", 0x00,
2866 "CR01", 0x01,
2867 "CR02", 0x02,
2868 "CR03", 0x03,
2869 "CR04", 0x04,
2870 "CR05", 0x05,
2871 "CR06", 0x06,
2872 "CR07", 0x07,
2873 "CR08", 0x08,
2874 "CR09", 0x09,
2875 "CR0A", 0x0A,
2876 "CR0B", 0x0B,
2877 "CR0C", 0x0C,
2878 "CR0D", 0x0D,
2879 "CR0E", 0x0E,
2880 "CR0F", 0x0F,
2881 "CR10", 0x10,
2882 "CR11", 0x11,
2883 "CR12", 0x12,
2884 "CR13", 0x13,
2885 "CR14", 0x14,
2886 "CR15", 0x15,
2887 "CR16", 0x16,
2888 "CR17", 0x17,
2889 "CR18", 0x18,
2890 "CR22", 0x22,
2891 "CR24", 0x24,
2892 "CR26", 0x26,
2893 "CR2D", 0x2D,
2894 "CR2E", 0x2E,
2895 "CR2F", 0x2F,
2896 "CR30", 0x30,
2897 "CR31", 0x31,
2898 "CR32", 0x32,
2899 "CR33", 0x33,
2900 "CR34", 0x34,
2901 "CR35", 0x35,
2902 "CR36", 0x36,
2903 "CR37", 0x37,
2904 "CR38", 0x38,
2905 "CR39", 0x39,
2906 "CR3A", 0x3A,
2907 "CR3B", 0x3B,
2908 "CR3C", 0x3C,
2909 "CR3D", 0x3D,
2910 "CR3E", 0x3E,
2911 "CR3F", 0x3F,
2912 NULL);
2913
2914 dev_dbg(info->device, "\n");
2915
2916 dev_dbg(info->device, "VGA SEQ register dump:\n");
2917
2918 cirrusfb_dbg_print_regs(info, regbase, SEQ,
2919 "SR00", 0x00,
2920 "SR01", 0x01,
2921 "SR02", 0x02,
2922 "SR03", 0x03,
2923 "SR04", 0x04,
2924 "SR08", 0x08,
2925 "SR09", 0x09,
2926 "SR0A", 0x0A,
2927 "SR0B", 0x0B,
2928 "SR0D", 0x0D,
2929 "SR10", 0x10,
2930 "SR11", 0x11,
2931 "SR12", 0x12,
2932 "SR13", 0x13,
2933 "SR14", 0x14,
2934 "SR15", 0x15,
2935 "SR16", 0x16,
2936 "SR17", 0x17,
2937 "SR18", 0x18,
2938 "SR19", 0x19,
2939 "SR1A", 0x1A,
2940 "SR1B", 0x1B,
2941 "SR1C", 0x1C,
2942 "SR1D", 0x1D,
2943 "SR1E", 0x1E,
2944 "SR1F", 0x1F,
2945 NULL);
2946
2947 dev_dbg(info->device, "\n");
2948 }
2949
2950 #endif
2951