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