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