1 /* $Id: creatorfb.c,v 1.17 1998/12/28 11:23:37 jj Exp $
2 * creatorfb.c: Creator/Creator3D frame buffer driver
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
7 #include <linux/module.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/errno.h>
11 #include <linux/string.h>
13 #include <linux/tty.h>
14 #include <linux/malloc.h>
15 #include <linux/vmalloc.h>
16 #include <linux/delay.h>
17 #include <linux/interrupt.h>
19 #include <linux/init.h>
20 #include <linux/selection.h>
22 #include <video/sbusfb.h>
24 #define FFB_SFB8R_VOFF 0x00000000
25 #define FFB_SFB8G_VOFF 0x00400000
26 #define FFB_SFB8B_VOFF 0x00800000
27 #define FFB_SFB8X_VOFF 0x00c00000
28 #define FFB_SFB32_VOFF 0x01000000
29 #define FFB_SFB64_VOFF 0x02000000
30 #define FFB_FBC_REGS_VOFF 0x04000000
31 #define FFB_BM_FBC_REGS_VOFF 0x04002000
32 #define FFB_DFB8R_VOFF 0x04004000
33 #define FFB_DFB8G_VOFF 0x04404000
34 #define FFB_DFB8B_VOFF 0x04804000
35 #define FFB_DFB8X_VOFF 0x04c04000
36 #define FFB_DFB24_VOFF 0x05004000
37 #define FFB_DFB32_VOFF 0x06004000
38 #define FFB_DFB422A_VOFF 0x07004000 /* DFB 422 mode write to A */
39 #define FFB_DFB422AD_VOFF 0x07804000 /* DFB 422 mode with line doubling */
40 #define FFB_DFB24B_VOFF 0x08004000 /* DFB 24bit mode write to B */
41 #define FFB_DFB422B_VOFF 0x09004000 /* DFB 422 mode write to B */
42 #define FFB_DFB422BD_VOFF 0x09804000 /* DFB 422 mode with line doubling */
43 #define FFB_SFB16Z_VOFF 0x0a004000 /* 16bit mode Z planes */
44 #define FFB_SFB8Z_VOFF 0x0a404000 /* 8bit mode Z planes */
45 #define FFB_SFB422_VOFF 0x0ac04000 /* SFB 422 mode write to A/B */
46 #define FFB_SFB422D_VOFF 0x0b404000 /* SFB 422 mode with line doubling */
47 #define FFB_FBC_KREGS_VOFF 0x0bc04000
48 #define FFB_DAC_VOFF 0x0bc06000
49 #define FFB_PROM_VOFF 0x0bc08000
50 #define FFB_EXP_VOFF 0x0bc18000
52 #define FFB_SFB8R_POFF 0x04000000
53 #define FFB_SFB8G_POFF 0x04400000
54 #define FFB_SFB8B_POFF 0x04800000
55 #define FFB_SFB8X_POFF 0x04c00000
56 #define FFB_SFB32_POFF 0x05000000
57 #define FFB_SFB64_POFF 0x06000000
58 #define FFB_FBC_REGS_POFF 0x00600000
59 #define FFB_BM_FBC_REGS_POFF 0x00600000
60 #define FFB_DFB8R_POFF 0x01000000
61 #define FFB_DFB8G_POFF 0x01400000
62 #define FFB_DFB8B_POFF 0x01800000
63 #define FFB_DFB8X_POFF 0x01c00000
64 #define FFB_DFB24_POFF 0x02000000
65 #define FFB_DFB32_POFF 0x03000000
66 #define FFB_FBC_KREGS_POFF 0x00610000
67 #define FFB_DAC_POFF 0x00400000
68 #define FFB_PROM_POFF 0x00000000
69 #define FFB_EXP_POFF 0x00200000
72 #define FFB_DRAWOP_DOT 0x00
73 #define FFB_DRAWOP_AADOT 0x01
74 #define FFB_DRAWOP_BRLINECAP 0x02
75 #define FFB_DRAWOP_BRLINEOPEN 0x03
76 #define FFB_DRAWOP_DDLINE 0x04
77 #define FFB_DRAWOP_AALINE 0x05
78 #define FFB_DRAWOP_TRIANGLE 0x06
79 #define FFB_DRAWOP_POLYGON 0x07
80 #define FFB_DRAWOP_RECTANGLE 0x08
81 #define FFB_DRAWOP_FASTFILL 0x09
82 #define FFB_DRAWOP_BCOPY 0x0a
83 #define FFB_DRAWOP_VSCROLL 0x0b
85 /* Pixel processor control */
87 #define FFB_PPC_FW_DISABLE 0x800000
88 #define FFB_PPC_FW_ENABLE 0xc00000
90 #define FFB_PPC_ACE_DISABLE 0x040000
91 #define FFB_PPC_ACE_AUX_SUB 0x080000
92 #define FFB_PPC_ACE_AUX_ADD 0x0c0000
94 #define FFB_PPC_DCE_DISABLE 0x020000
95 #define FFB_PPC_DCE_ENABLE 0x030000
97 #define FFB_PPC_ABE_DISABLE 0x008000
98 #define FFB_PPC_ABE_ENABLE 0x00c000
100 #define FFB_PPC_VCE_DISABLE 0x001000
101 #define FFB_PPC_VCE_2D 0x002000
102 #define FFB_PPC_VCE_3D 0x003000
104 #define FFB_PPC_APE_DISABLE 0x000800
105 #define FFB_PPC_APE_ENABLE 0x000c00
106 /* Transparent background */
107 #define FFB_PPC_TBE_OPAQUE 0x000200
108 #define FFB_PPC_TBE_TRANSPARENT 0x000300
110 #define FFB_PPC_ZS_VAR 0x000080
111 #define FFB_PPC_ZS_CONST 0x0000c0
113 #define FFB_PPC_YS_VAR 0x000020
114 #define FFB_PPC_YS_CONST 0x000030
116 #define FFB_PPC_XS_WID 0x000004
117 #define FFB_PPC_XS_VAR 0x000008
118 #define FFB_PPC_XS_CONST 0x00000c
119 /* Color (BGR) source */
120 #define FFB_PPC_CS_VAR 0x000002
121 #define FFB_PPC_CS_CONST 0x000003
123 #define FFB_ROP_NEW 0x83
125 #define FFB_UCSR_FIFO_MASK 0x00000fff
126 #define FFB_UCSR_FB_BUSY 0x01000000
127 #define FFB_UCSR_RP_BUSY 0x02000000
128 #define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
129 #define FFB_UCSR_READ_ERR 0x40000000
130 #define FFB_UCSR_FIFO_OVFL 0x80000000
131 #define FFB_UCSR_ALL_ERRORS (FFB_UCSR_READ_ERR|FFB_UCSR_FIFO_OVFL)
134 /* Next vertex registers */
164 /* Setup unit vertex state register */
168 /* Control registers */
177 volatile u32 vclipmin
;
178 volatile u32 vclipmax
;
179 volatile u32 vclipzmin
;
180 volatile u32 vclipzmax
;
188 volatile u32 blendc1
;
189 volatile u32 blendc2
;
190 volatile u32 fbramitc
;
194 volatile u32 matchab
;
205 volatile u32 fillmode
;
206 volatile u32 fbramwac
;
211 volatile u32 clip0min
;
212 volatile u32 clip0max
;
213 volatile u32 clip1min
;
214 volatile u32 clip1max
;
215 volatile u32 clip2min
;
216 volatile u32 clip2max
;
217 volatile u32 clip3min
;
218 volatile u32 clip3max
;
220 /* New 3dRAM III support regs */
221 volatile u32 rawblend2
;
222 volatile u32 rawpreblend
;
223 volatile u32 rawstencil
;
224 volatile u32 rawstencilctl
;
225 volatile u32 threedram1
;
226 volatile u32 threedram2
;
228 volatile u32 rawclrdepth
;
229 volatile u32 rawpmask
;
230 volatile u32 rawcsrc
;
231 volatile u32 rawmatch
;
232 volatile u32 rawmagn
;
233 volatile u32 rawropblend
;
236 volatile u32 fbramid
;
240 volatile u32 fontlpat
;
244 volatile u32 fontinc
;
248 volatile u32 preblend
;
249 volatile u32 stencil
;
250 volatile u32 stencilctl
;
256 volatile u32 widpmask
;
266 volatile u32 pattern
[32];
279 static __inline__
void FFBFifo(struct ffb_fbc
*ffb
, int n
)
284 if((ffb
->ucsr
& FFB_UCSR_FIFO_MASK
) >= (n
+ 4))
286 if((ffb
->ucsr
& FFB_UCSR_ALL_ERRORS
) != 0)
287 ffb
->ucsr
= FFB_UCSR_ALL_ERRORS
;
288 } while(--limit
> 0);
291 static __inline__
void FFBWait(struct ffb_fbc
*ffb
)
296 if((ffb
->ucsr
& FFB_UCSR_ALL_BUSY
) == 0)
298 if((ffb
->ucsr
& FFB_UCSR_ALL_ERRORS
) != 0)
299 ffb
->ucsr
= FFB_UCSR_ALL_ERRORS
;
300 } while(--limit
> 0);
310 static struct sbus_mmap_map ffb_mmap_map
[] = {
311 { FFB_SFB8R_VOFF
, FFB_SFB8R_POFF
, 0x0400000 },
312 { FFB_SFB8G_VOFF
, FFB_SFB8G_POFF
, 0x0400000 },
313 { FFB_SFB8B_VOFF
, FFB_SFB8B_POFF
, 0x0400000 },
314 { FFB_SFB8X_VOFF
, FFB_SFB8X_POFF
, 0x0400000 },
315 { FFB_SFB32_VOFF
, FFB_SFB32_POFF
, 0x1000000 },
316 { FFB_SFB64_VOFF
, FFB_SFB64_POFF
, 0x2000000 },
317 { FFB_FBC_REGS_VOFF
, FFB_FBC_REGS_POFF
, 0x0002000 },
318 { FFB_BM_FBC_REGS_VOFF
, FFB_BM_FBC_REGS_POFF
, 0x0002000 },
319 { FFB_DFB8R_VOFF
, FFB_DFB8R_POFF
, 0x0400000 },
320 { FFB_DFB8G_VOFF
, FFB_DFB8G_POFF
, 0x0400000 },
321 { FFB_DFB8B_VOFF
, FFB_DFB8B_POFF
, 0x0400000 },
322 { FFB_DFB8X_VOFF
, FFB_DFB8X_POFF
, 0x0400000 },
323 { FFB_DFB24_VOFF
, FFB_DFB24_POFF
, 0x1000000 },
324 { FFB_DFB32_VOFF
, FFB_DFB32_POFF
, 0x1000000 },
325 { FFB_FBC_KREGS_VOFF
, FFB_FBC_KREGS_POFF
, 0x0002000 },
326 { FFB_DAC_VOFF
, FFB_DAC_POFF
, 0x0002000 },
327 { FFB_PROM_VOFF
, FFB_PROM_POFF
, 0x0010000 },
328 { FFB_EXP_VOFF
, FFB_EXP_POFF
, 0x0002000 },
332 static void ffb_setup(struct display
*p
)
338 static void ffb_clear(struct vc_data
*conp
, struct display
*p
, int sy
, int sx
,
339 int height
, int width
)
341 struct fb_info_sbusfb
*fb
= (struct fb_info_sbusfb
*)p
->fb_info
;
342 register struct ffb_fbc
*fbc
= fb
->s
.ffb
.fbc
;
347 fbc
->fg
= ((u32
*)p
->dispsw_data
)[attr_bgcol_ec(p
,conp
)];
348 fbc
->drawop
= FFB_DRAWOP_RECTANGLE
;
350 if (fontheightlog(p
)) {
351 y
= sy
<< fontheightlog(p
); h
= height
<< fontheightlog(p
);
353 y
= sy
* fontheight(p
); h
= height
* fontheight(p
);
355 if (fontwidthlog(p
)) {
356 x
= sx
<< fontwidthlog(p
); w
= width
<< fontwidthlog(p
);
358 x
= sx
* fontwidth(p
); w
= width
* fontwidth(p
);
360 fbc
->by
= y
+ fb
->y_margin
;
361 fbc
->bx
= x
+ fb
->x_margin
;
366 static void ffb_fill(struct fb_info_sbusfb
*fb
, struct display
*p
, int s
,
367 int count
, unsigned short *boxes
)
369 register struct ffb_fbc
*fbc
= fb
->s
.ffb
.fbc
;
373 fbc
->fg
= ((u32
*)p
->dispsw_data
)[attr_bgcol(p
,s
)];
374 fbc
->drawop
= FFB_DRAWOP_RECTANGLE
;
375 while (count
-- > 0) {
379 fbc
->bh
= boxes
[3] - boxes
[1];
380 fbc
->bw
= boxes
[2] - boxes
[0];
385 static void ffb_putc(struct vc_data
*conp
, struct display
*p
, int c
, int yy
, int xx
)
387 struct fb_info_sbusfb
*fb
= (struct fb_info_sbusfb
*)p
->fb_info
;
388 register struct ffb_fbc
*fbc
= fb
->s
.ffb
.fbc
;
392 if (fontheightlog(p
)) {
393 xy
= (yy
<< (16 + fontheightlog(p
)));
394 i
= ((c
& p
->charmask
) << fontheightlog(p
));
396 xy
= ((yy
* fontheight(p
)) << 16);
397 i
= (c
& p
->charmask
) * fontheight(p
);
399 if (fontwidth(p
) <= 8)
400 fd
= p
->fontdata
+ i
;
402 fd
= p
->fontdata
+ (i
<< 1);
404 xy
+= (xx
<< fontwidthlog(p
)) + fb
->s
.ffb
.xy_margin
;
406 xy
+= (xx
* fontwidth(p
)) + fb
->s
.ffb
.xy_margin
;
409 fbc
->fg
= ((u32
*)p
->dispsw_data
)[attr_fgcol(p
,c
)];
410 fbc
->bg
= ((u32
*)p
->dispsw_data
)[attr_bgcol(p
,c
)];
411 fbc
->fontw
= fontwidth(p
);
412 fbc
->fontinc
= 0x10000;
414 FFBFifo(fbc
, fontheight(p
));
415 if (fontwidth(p
) <= 8) {
416 for (i
= 0; i
< fontheight(p
); i
++)
417 fbc
->font
= *fd
++ << 24;
419 for (i
= 0; i
< fontheight(p
); i
++) {
420 fbc
->font
= *(u16
*)fd
<< 16;
426 static void ffb_putcs(struct vc_data
*conp
, struct display
*p
, const unsigned short *s
,
427 int count
, int yy
, int xx
)
429 struct fb_info_sbusfb
*fb
= (struct fb_info_sbusfb
*)p
->fb_info
;
430 register struct ffb_fbc
*fbc
= fb
->s
.ffb
.fbc
;
432 u8
*fd1
, *fd2
, *fd3
, *fd4
;
436 fbc
->fg
= ((u32
*)p
->dispsw_data
)[attr_fgcol(p
,*s
)];
437 fbc
->bg
= ((u32
*)p
->dispsw_data
)[attr_bgcol(p
,*s
)];
438 xy
= fb
->s
.ffb
.xy_margin
;
440 xy
+= (xx
<< fontwidthlog(p
));
442 xy
+= xx
* fontwidth(p
);
443 if (fontheightlog(p
))
444 xy
+= (yy
<< (16 + fontheightlog(p
)));
446 xy
+= ((yy
* fontheight(p
)) << 16);
447 if (fontwidth(p
) <= 8) {
451 fbc
->fontw
= 4 * fontwidth(p
);
452 fbc
->fontinc
= 0x10000;
454 if (fontheightlog(p
)) {
455 fd1
= p
->fontdata
+ ((*s
++ & p
->charmask
) << fontheightlog(p
));
456 fd2
= p
->fontdata
+ ((*s
++ & p
->charmask
) << fontheightlog(p
));
457 fd3
= p
->fontdata
+ ((*s
++ & p
->charmask
) << fontheightlog(p
));
458 fd4
= p
->fontdata
+ ((*s
++ & p
->charmask
) << fontheightlog(p
));
460 fd1
= p
->fontdata
+ ((*s
++ & p
->charmask
) * fontheight(p
));
461 fd2
= p
->fontdata
+ ((*s
++ & p
->charmask
) * fontheight(p
));
462 fd3
= p
->fontdata
+ ((*s
++ & p
->charmask
) * fontheight(p
));
463 fd4
= p
->fontdata
+ ((*s
++ & p
->charmask
) * fontheight(p
));
465 FFBFifo(fbc
, fontheight(p
));
466 if (fontwidth(p
) == 8) {
467 for (i
= 0; i
< fontheight(p
); i
++)
468 fbc
->font
= ((u32
)*fd4
++) | ((((u32
)*fd3
++) | ((((u32
)*fd2
++) | (((u32
)*fd1
++)
472 for (i
= 0; i
< fontheight(p
); i
++)
473 fbc
->font
= (((u32
)*fd4
++) | ((((u32
)*fd3
++) | ((((u32
)*fd2
++) | (((u32
)*fd1
++)
474 << fontwidth(p
))) << fontwidth(p
))) << fontwidth(p
))) << (24 - 3 * fontwidth(p
));
475 xy
+= 4 * fontwidth(p
);
482 fbc
->fontw
= 2 * fontwidth(p
);
483 fbc
->fontinc
= 0x10000;
485 if (fontheightlog(p
)) {
486 fd1
= p
->fontdata
+ ((*s
++ & p
->charmask
) << (fontheightlog(p
) + 1));
487 fd2
= p
->fontdata
+ ((*s
++ & p
->charmask
) << (fontheightlog(p
) + 1));
489 fd1
= p
->fontdata
+ (((*s
++ & p
->charmask
) * fontheight(p
)) << 1);
490 fd2
= p
->fontdata
+ (((*s
++ & p
->charmask
) * fontheight(p
)) << 1);
492 FFBFifo(fbc
, fontheight(p
));
493 for (i
= 0; i
< fontheight(p
); i
++) {
494 fbc
->font
= ((((u32
)*(u16
*)fd1
) << fontwidth(p
)) | ((u32
)*(u16
*)fd2
)) << (16 - fontwidth(p
));
497 xy
+= 2 * fontwidth(p
);
503 fbc
->fontw
= fontwidth(p
);
504 fbc
->fontinc
= 0x10000;
506 if (fontheightlog(p
))
507 i
= ((*s
++ & p
->charmask
) << fontheightlog(p
));
509 i
= ((*s
++ & p
->charmask
) * fontheight(p
));
510 FFBFifo(fbc
, fontheight(p
));
511 if (fontwidth(p
) <= 8) {
512 fd1
= p
->fontdata
+ i
;
513 for (i
= 0; i
< fontheight(p
); i
++)
514 fbc
->font
= *fd1
++ << 24;
516 fd1
= p
->fontdata
+ (i
<< 1);
517 for (i
= 0; i
< fontheight(p
); i
++) {
518 fbc
->font
= *(u16
*)fd1
<< 16;
526 static void ffb_revc(struct display
*p
, int xx
, int yy
)
528 /* Not used if hw cursor */
531 static void ffb_loadcmap (struct fb_info_sbusfb
*fb
, struct display
*p
, int index
, int count
)
533 struct ffb_dac
*dac
= fb
->s
.ffb
.dac
;
536 dac
->type
= 0x2000 | index
;
537 for (i
= index
; j
--; i
++)
538 /* Feed the colors in :)) */
539 dac
->value
= ((fb
->color_map
CM(i
,0))) |
540 ((fb
->color_map
CM(i
,1)) << 8) |
541 ((fb
->color_map
CM(i
,2)) << 16);
544 for (i
= index
, j
= count
; i
< 16 && j
--; i
++)
545 ((u32
*)p
->dispsw_data
)[i
] = ((fb
->color_map
CM(i
,0))) |
546 ((fb
->color_map
CM(i
,1)) << 8) |
547 ((fb
->color_map
CM(i
,2)) << 16);
550 static struct display_switch ffb_dispsw __initdata
= {
551 ffb_setup
, fbcon_redraw_bmove
, ffb_clear
, ffb_putc
, ffb_putcs
, ffb_revc
,
552 NULL
, NULL
, NULL
, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
555 static void ffb_margins (struct fb_info_sbusfb
*fb
, struct display
*p
, int x_margin
, int y_margin
)
557 fb
->s
.ffb
.xy_margin
= (y_margin
<< 16) + x_margin
;
558 p
->screen_base
+= 8192 * (y_margin
- fb
->y_margin
) + 4 * (x_margin
- fb
->x_margin
);
561 static inline void ffb_curs_enable (struct fb_info_sbusfb
*fb
, int enable
)
563 struct ffb_dac
*dac
= fb
->s
.ffb
.dac
;
566 if (fb
->s
.ffb
.dac_rev
<= 2)
567 dac
->value2
= enable
? 3 : 0;
569 dac
->value2
= enable
? 0 : 3;
572 static void ffb_setcursormap (struct fb_info_sbusfb
*fb
, u8
*red
, u8
*green
, u8
*blue
)
574 struct ffb_dac
*dac
= fb
->s
.ffb
.dac
;
576 ffb_curs_enable (fb
, 0);
578 dac
->value2
= (red
[0] | (green
[0]<<8) | (blue
[0]<<16));
579 dac
->value2
= (red
[1] | (green
[1]<<8) | (blue
[1]<<16));
582 /* Set cursor shape */
583 static void ffb_setcurshape (struct fb_info_sbusfb
*fb
)
585 struct ffb_dac
*dac
= fb
->s
.ffb
.dac
;
588 ffb_curs_enable (fb
, 0);
589 for (j
= 0; j
< 2; j
++) {
590 dac
->type2
= j
? 0 : 0x80;
591 for (i
= 0; i
< 0x40; i
++) {
592 if (fb
->cursor
.size
.fbx
<= 32) {
593 dac
->value2
= fb
->cursor
.bits
[j
][i
];
596 dac
->value2
= fb
->cursor
.bits
[j
][2*i
];
597 dac
->value2
= fb
->cursor
.bits
[j
][2*i
+1];
603 /* Load cursor information */
604 static void ffb_setcursor (struct fb_info_sbusfb
*fb
)
606 struct ffb_dac
*dac
= fb
->s
.ffb
.dac
;
607 struct cg_cursor
*c
= &fb
->cursor
;
610 /* Should this be just 0x7ff??
611 Should I do some margin handling and setcurshape in that case? */
612 dac
->value2
= (((c
->cpos
.fby
- c
->chot
.fby
) & 0xffff) << 16)
613 |((c
->cpos
.fbx
- c
->chot
.fbx
) & 0xffff);
614 ffb_curs_enable (fb
, fb
->cursor
.enable
);
617 static void ffb_switch_from_graph (struct fb_info_sbusfb
*fb
)
619 register struct ffb_fbc
*fbc
= fb
->s
.ffb
.fbc
;
623 fbc
->ppc
= FFB_PPC_VCE_DISABLE
|FFB_PPC_TBE_OPAQUE
|FFB_PPC_APE_DISABLE
|FFB_PPC_CS_CONST
;
624 fbc
->fbc
= 0x2000707f;
625 fbc
->rop
= FFB_ROP_NEW
;
626 fbc
->pmask
= 0xffffffff;
630 static char idstring
[60] __initdata
= { 0 };
632 __initfunc(char *creatorfb_init(struct fb_info_sbusfb
*fb
))
634 struct fb_fix_screeninfo
*fix
= &fb
->fix
;
635 struct fb_var_screeninfo
*var
= &fb
->var
;
636 struct display
*disp
= &fb
->disp
;
637 struct fbtype
*type
= &fb
->type
;
638 struct linux_prom64_registers regs
[2*PROMREG_MAX
];
643 if (prom_getproperty(fb
->prom_node
, "reg", (void *) regs
, sizeof(regs
)) <= 0)
646 disp
->dispsw_data
= (void *)kmalloc(16 * sizeof(u32
), GFP_KERNEL
);
647 if (!disp
->dispsw_data
)
649 memset(disp
->dispsw_data
, 0, 16 * sizeof(u32
));
651 prom_getstring(fb
->prom_node
, "name", name
, sizeof(name
));
652 if (!strcmp(name
, "SUNW,afb"))
655 btype
= prom_getintdefault(fb
->prom_node
, "board_type", 0);
657 strcpy(fb
->info
.modename
, "Creator");
659 if ((btype
& 7) == 3)
660 strcpy(fix
->id
, "Creator 3D");
662 strcpy(fix
->id
, "Creator");
664 strcpy(fix
->id
, "Elite 3D");
666 fix
->visual
= FB_VISUAL_TRUECOLOR
;
667 fix
->line_length
= 8192;
668 fix
->accel
= FB_ACCEL_SUN_CREATOR
;
670 var
->bits_per_pixel
= 32;
671 var
->green
.offset
= 8;
672 var
->blue
.offset
= 16;
673 var
->accel_flags
= FB_ACCELF_TEXT
;
675 disp
->scrollmode
= SCROLL_YREDRAW
;
676 disp
->screen_base
= (char *)__va(regs
[0].phys_addr
) + FFB_DFB24_POFF
+ 8192 * fb
->y_margin
+ 4 * fb
->x_margin
;
677 fb
->s
.ffb
.xy_margin
= (fb
->y_margin
<< 16) + fb
->x_margin
;
678 fb
->s
.ffb
.fbc
= (struct ffb_fbc
*)((char *)__va(regs
[0].phys_addr
) + FFB_FBC_REGS_POFF
);
679 fb
->s
.ffb
.dac
= (struct ffb_dac
*)((char *)__va(regs
[0].phys_addr
) + FFB_DAC_POFF
);
680 fb
->dispsw
= ffb_dispsw
;
682 fb
->margins
= ffb_margins
;
683 fb
->loadcmap
= ffb_loadcmap
;
684 fb
->setcursor
= ffb_setcursor
;
685 fb
->setcursormap
= ffb_setcursormap
;
686 fb
->setcurshape
= ffb_setcurshape
;
687 fb
->switch_from_graph
= ffb_switch_from_graph
;
690 /* If there are any read errors or fifo overflow conditions,
693 if((fb
->s
.ffb
.fbc
->ucsr
& FFB_UCSR_ALL_ERRORS
) != 0)
694 fb
->s
.ffb
.fbc
->ucsr
= FFB_UCSR_ALL_ERRORS
;
696 ffb_switch_from_graph(fb
);
698 fb
->physbase
= regs
[0].phys_addr
;
699 fb
->mmap_map
= ffb_mmap_map
;
701 fb
->cursor
.hwsize
.fbx
= 64;
702 fb
->cursor
.hwsize
.fby
= 64;
706 fb
->s
.ffb
.dac
->type
= 0x8000;
707 fb
->s
.ffb
.dac_rev
= (fb
->s
.ffb
.dac
->value
>> 0x1c);
709 i
= prom_getintdefault (fb
->prom_node
, "board_type", 8);
711 sprintf(idstring
, "%s at %016lx type %d DAC %d", fix
->id
, regs
[0].phys_addr
, i
, fb
->s
.ffb
.dac_rev
);