2 * We've been given MAC frame buffer info by the booter. Now go set it up
5 #include <linux/module.h>
6 #include <linux/kernel.h>
7 #include <linux/sched.h>
8 #include <linux/errno.h>
9 #include <linux/string.h>
11 #include <linux/tty.h>
12 #include <linux/malloc.h>
13 #include <linux/delay.h>
14 #include <linux/nubus.h>
15 #include <linux/init.h>
17 #include <asm/setup.h>
18 #include <asm/bootinfo.h>
19 #include <asm/uaccess.h>
20 #include <asm/pgtable.h>
22 #include <asm/macintosh.h>
25 #include <video/fbcon.h>
26 /* conditionalize these ?? */
27 #include <video/fbcon-mfb.h>
28 #include <video/fbcon-cfb2.h>
29 #include <video/fbcon-cfb4.h>
30 #include <video/fbcon-cfb8.h>
32 #define arraysize(x) (sizeof(x)/sizeof(*(x)))
34 static struct fb_var_screeninfo macfb_defined
={
35 0,0,0,0, /* W,H, W, H (virtual) load xres,xres_virtual*/
36 0,0, /* virtual -> visible no offset */
37 8, /* depth -> load bits_per_pixel */
42 {0,0,0}, /* transparency */
43 0, /* standard pixel format */
45 274,195, /* 14" monitor *Mikael Nykvist's anyway* */
46 0, /* The only way to accelerate a mac is .. */
48 0L,0L,0, /* No sync info */
49 FB_VMODE_NONINTERLACED
,
53 #define NUM_TOTAL_MODES 1
54 #define NUM_PREDEF_MODES 1
56 static struct display disp
;
57 static struct fb_info fb_info
;
59 static int inverse
= 0;
66 static int currcon
= 0;
67 static int current_par_valid
= 0;
68 struct macfb_par current_par
;
70 static int mac_xres
,mac_yres
,mac_depth
, mac_xbytes
, mac_vxres
;
71 static unsigned long mac_videobase
;
72 static unsigned long mac_videosize
;
75 * Open/Release the frame buffer device
78 static int macfb_open(struct fb_info
*info
, int user
)
81 * Nothing, only a usage count for the moment
87 static int macfb_release(struct fb_info
*info
, int user
)
93 static void macfb_encode_var(struct fb_var_screeninfo
*var
,
94 struct macfb_par
*par
)
96 memset(var
, 0, sizeof(struct fb_var_screeninfo
));
99 var
->xres_virtual
=mac_vxres
;
100 var
->yres_virtual
=var
->yres
;
103 var
->bits_per_pixel
= mac_depth
;
105 var
->transp
.offset
=0;
106 var
->transp
.length
=0;
107 var
->transp
.msb_right
=0;
112 var
->vmode
=FB_VMODE_NONINTERLACED
;
125 static void macfb_get_par(struct macfb_par
*par
)
130 static void macfb_set_par(struct macfb_par
*par
)
135 static int fb_update_var(int con
, struct fb_info
*info
)
140 static int do_fb_set_var(struct fb_var_screeninfo
*var
, int isactive
)
142 struct macfb_par par
;
145 macfb_encode_var(var
, &par
);
149 extern int console_loglevel
;
151 static void macfb_encode_fix(struct fb_fix_screeninfo
*fix
,
152 struct macfb_par
*par
)
154 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
155 strcpy(fix
->id
,"Macintosh");
158 * fbmem.c accepts non page aligned mappings now!
160 fix
->smem_start
=(char *)mac_videobase
;
161 fix
->smem_len
=mac_videosize
;
162 fix
->type
= FB_TYPE_PACKED_PIXELS
;
164 fix
->visual
= FB_VISUAL_MONO01
;
166 fix
->visual
= FB_VISUAL_STATIC_PSEUDOCOLOR
;
170 fix
->line_length
=mac_xbytes
;
174 static int macfb_get_fix(struct fb_fix_screeninfo
*fix
, int con
,
175 struct fb_info
*info
)
177 struct macfb_par par
;
179 macfb_encode_fix(fix
, &par
);
183 static int macfb_get_var(struct fb_var_screeninfo
*var
, int con
,
184 struct fb_info
*info
)
186 struct macfb_par par
;
190 macfb_encode_var(var
, &par
);
193 *var
=fb_display
[con
].var
;
197 static void macfb_set_disp(int con
)
199 struct fb_fix_screeninfo fix
;
200 struct display
*display
;
203 display
= &fb_display
[con
];
205 display
= &disp
; /* used during initialization */
207 macfb_get_fix(&fix
, con
, 0);
209 display
->screen_base
= fix
.smem_start
;
210 display
->visual
= fix
.visual
;
211 display
->type
= fix
.type
;
212 display
->type_aux
= fix
.type_aux
;
213 display
->ypanstep
= fix
.ypanstep
;
214 display
->ywrapstep
= fix
.ywrapstep
;
215 display
->line_length
= fix
.line_length
;
216 display
->next_line
= fix
.line_length
;
217 display
->can_soft_blank
= 0;
219 (fix
.visual
== FB_VISUAL_MONO01
? !inverse
: inverse
);
224 display
->dispsw
= &fbcon_mfb
;
227 #ifdef FBCON_HAS_CFB2
229 display
->dispsw
= &fbcon_cfb2
;
232 #ifdef FBCON_HAS_CFB4
234 display
->dispsw
= &fbcon_cfb4
;
237 #ifdef FBCON_HAS_CFB8
239 display
->dispsw
= &fbcon_cfb8
;
243 display
->dispsw
= &fbcon_dummy
;
248 static int macfb_set_var(struct fb_var_screeninfo
*var
, int con
,
249 struct fb_info
*info
)
253 if ((err
=do_fb_set_var(var
, 1)))
259 * Color map handling - hardcoded maps!!
261 * 2.0 color map primitives, copied from atafb.c
265 * should be kmalloc'ed on request
267 static short red256
[256], green256
[256], blue256
[256];
269 static short red16
[]=
270 { 0x0000,0x0000,0x0000,0x0000,0x8080,0x8080,0x8080,0xc0c0,
271 0x8080,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff};
272 static short green16
[]=
273 { 0x0000,0x0000,0x8080,0x8080,0x0000,0x0000,0x8080,0xc0c0,
274 0x8080,0x0000,0xffff,0xffff,0x0000,0x0000,0xffff,0xffff};
275 static short blue16
[]=
276 { 0x0000,0x8080,0x0000,0x8080,0x0000,0x8080,0x0000,0xc0c0,
277 0x8080,0xffff,0x0000,0xffff,0x0000,0xffff,0x0000,0xffff};
280 { 0x0000,0x8080,0xffff,0xffff};
281 static short green4
[]=
282 { 0x0000,0x8080,0x0000,0xffff};
283 static short blue4
[]=
284 { 0x0000,0x8080,0x0000,0xffff};
288 static short green2
[]=
290 static short blue2
[]=
293 struct fb_cmap default_256_colors
= { 0, 256, red256
, green256
, blue256
, NULL
};
294 struct fb_cmap default_16_colors
= { 0, 16, red16
, green16
, blue16
, NULL
};
295 struct fb_cmap default_4_colors
= { 0, 4, red4
, green4
, blue4
, NULL
};
296 struct fb_cmap default_2_colors
= { 0, 2, red2
, green2
, blue2
, NULL
};
298 static int mac_set_cmap256(struct fb_cmap
* cmap
)
301 unsigned short *red
,*green
,*blue
;
302 unsigned short cval
[] = {0xffff, 0xcccc, 0x9999,
303 0x6666, 0x3333, 0x0000 };
304 unsigned short gval
[] = {0x0a0a, 0x1414, 0x1e1e,
305 0x2828, 0x3232, 0x3c3c,
306 0x4646, 0x5050, 0x5a5a,
307 0x6464, 0x6e6e, 0x7878,
308 0x8282, 0x8c8c, 0x9696,
309 0xa0a0, 0xaaaa, 0xb4b4,
310 0xbebe, 0xc8c8, 0xd2d2,
311 0xdcdc, 0xe6e6, 0xf0f0};
323 for (i
=0 ; i
< 16 ; i
++) {
325 *green
++ = green16
[i
];
328 /* 216 colors (6x6x6) map) */
329 for (i
=16 ; i
< 232 ; i
++) {
330 *red
++ = cval
[(i
-16)/36];
331 *green
++ = cval
[((i
-16)/6)%6];
332 *blue
++ = cval
[(i
-16)%6];
335 for (i
=232 ; i
< 256 ; i
++) {
336 *red
= *green
= *blue
= gval
[i
-232];
344 static struct fb_cmap
* mac_get_default_cmap(int bpp
)
347 return &default_2_colors
;
349 return &default_4_colors
;
351 return &default_16_colors
;
352 return &default_256_colors
;
355 static void memcpy_fs(int fsfromto
, void *to
, void *from
, int len
)
359 memcpy(to
, from
, len
);
362 copy_from_user(to
, from
, len
);
365 copy_to_user(to
, from
, len
);
370 static void copy_cmap(struct fb_cmap
*from
, struct fb_cmap
*to
, int fsfromto
)
373 int tooff
=0, fromoff
=0;
375 if (to
->start
> from
->start
)
376 fromoff
=to
->start
-from
->start
;
378 tooff
=from
->start
-to
->start
;
380 if (size
> from
->len
-fromoff
)
381 size
=from
->len
-fromoff
;
384 size
*=sizeof(unsigned short);
385 memcpy_fs(fsfromto
, to
->red
+tooff
, from
->red
+fromoff
, size
);
386 memcpy_fs(fsfromto
, to
->green
+tooff
, from
->green
+fromoff
, size
);
387 memcpy_fs(fsfromto
, to
->blue
+tooff
, from
->blue
+fromoff
, size
);
388 if (from
->transp
&& to
->transp
)
389 memcpy_fs(fsfromto
, to
->transp
+tooff
, from
->transp
+fromoff
, size
);
392 static int macfb_get_cmap(struct fb_cmap
*cmap
, int kspc
, int con
,
393 struct fb_info
*info
)
396 printk("macfb_get_cmap: not supported!\n");
397 /* interferes with X11 */
398 if (console_loglevel
< 7)
400 if (con
== currcon
) /* current console? */
401 return fb_get_cmap(cmap
, kspc
, 0 /*offb_getcolreg*/, info
);
402 else if (fb_display
[con
].cmap
.len
) /* non default colormap? */
403 fb_copy_cmap(&fb_display
[con
].cmap
, cmap
, kspc
? 0 : 2);
405 fb_copy_cmap(fb_default_cmap(fb_display
[con
].var
.bits_per_pixel
),
408 copy_cmap(mac_get_default_cmap(fb_display
[con
].var
.bits_per_pixel
),
414 static int macfb_set_cmap(struct fb_cmap
*cmap
, int kspc
, int con
,
415 struct fb_info
*info
)
418 printk("macfb_set_cmap: not supported!\n");
419 if (console_loglevel
< 7)
421 if (!fb_display
[con
].cmap
.len
) { /* no colormap allocated? */
422 if ((err
= fb_alloc_cmap(&fb_display
[con
].cmap
,
423 1<<fb_display
[con
].var
.bits_per_pixel
, 0)))
426 if (con
== currcon
) /* current console? */
427 return fb_set_cmap(cmap
, kspc
, 1 /*offb_setcolreg*/, info
);
429 fb_copy_cmap(cmap
, &fb_display
[con
].cmap
, kspc
? 0 : 1);
434 static int macfb_pan_display(struct fb_var_screeninfo
*var
, int con
,
435 struct fb_info
*info
)
438 printk("macfb_pan: not supported!\n");
442 static int macfb_ioctl(struct inode
*inode
, struct file
*file
,
443 unsigned int cmd
, unsigned long arg
, int con
,
444 struct fb_info
*info
)
446 printk("macfb_ioctl: not supported!\n");
450 static struct fb_ops macfb_ops
= {
462 void macfb_setup(char *options
, int *ints
)
466 fb_info
.fontname
[0] = '\0';
468 if (!options
|| !*options
)
471 for(this_opt
=strtok(options
,","); this_opt
; this_opt
=strtok(NULL
,",")) {
472 if (!*this_opt
) continue;
474 if (! strcmp(this_opt
, "inverse"))
476 else if (!strncmp(this_opt
, "font:", 5)) {
477 strcpy(fb_info
.fontname
, this_opt
+5);
478 printk("macfb_setup: option %s\n", this_opt
);
483 static int macfb_switch(int con
, struct fb_info
*info
)
485 do_fb_set_var(&fb_display
[con
].var
,1);
490 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
492 static void macfb_blank(int blank
, struct fb_info
*info
)
498 * Nubus call back. This will give us our board identity and also
499 * other useful info we need later
502 static int nubus_video_card(struct nubus_device_specifier
*ns
, int slot
, struct nubus_type
*nt
)
504 if(nt
->category
==NUBUS_CAT_DISPLAY
)
506 /* Claim all video cards. We don't yet do driver specifics though. */
510 static struct nubus_device_specifier nb_video
={
515 void __init
macfb_init(void)
517 /* nubus_remap the video .. */
522 mac_xres
=mac_bi_data
.dimensions
&0xFFFF;
523 mac_yres
=(mac_bi_data
.dimensions
&0xFFFF0000)>>16;
524 mac_depth
=mac_bi_data
.videodepth
;
525 mac_xbytes
=mac_bi_data
.videorow
;
526 mac_vxres
= (mac_xbytes
/mac_depth
)*8;
527 mac_videosize
=mac_xbytes
*mac_yres
;
528 mac_videobase
=mac_bi_data
.videoaddr
;
530 printk("macfb_init: xres %d yres %d bpp %d addr %lx size %ld \n",
531 mac_xres
, mac_yres
, mac_depth
, mac_videobase
, mac_videosize
);
534 * Fill in the available video resolution
537 macfb_defined
.xres
=mac_xres
;
538 macfb_defined
.yres
=mac_yres
;
539 macfb_defined
.xres_virtual
=mac_vxres
;
540 macfb_defined
.yres_virtual
=mac_yres
;
541 macfb_defined
.bits_per_pixel
=mac_depth
;
545 * Let there be consoles..
547 strcpy(fb_info
.modename
, "Macintosh Builtin ");
548 fb_info
.changevar
= NULL
;
550 fb_info
.fbops
= &macfb_ops
;
552 fb_info
.switch_con
=&macfb_switch
;
553 fb_info
.updatevar
=&fb_update_var
;
554 fb_info
.blank
=&macfb_blank
;
555 fb_info
.flags
= FBINFO_FLAG_DEFAULT
;
556 do_fb_set_var(&macfb_defined
,1);
558 macfb_get_var(&disp
.var
, -1, &fb_info
);
562 * Fill in the 8 bit color table if required
565 mac_set_cmap256(&default_256_colors
);
568 * Register the nubus hook
571 register_nubus_device(&nb_video
);
573 if (register_framebuffer(&fb_info
) < 0)
578 printk("fb%d: %s frame buffer device using %ldK of video memory\n",
579 GET_FB_IDX(fb_info
.node
), fb_info
.modename
, mac_videosize
>>10);
584 * These two auxiliary debug functions should go away ASAP. Only usage:
585 * before the console output is up (after head.S come some other crucial