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