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