Import 2.4.0-test5pre6
[davej-history.git] / drivers / video / igafb.c
blobac176a8cf8c47bbcfa7dec351ea97fb86f204e39
1 /*
2 * linux/drivers/video/igafb.c -- Frame buffer device for IGA 1682
4 * Copyright (C) 1998 Vladimir Roganov and Gleb Raiko
6 * This driver is partly based on the Frame buffer device for ATI Mach64
7 * and partially on VESA-related code.
9 * Copyright (C) 1997-1998 Geert Uytterhoeven
10 * Copyright (C) 1998 Bernd Harries
11 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file COPYING in the main directory of this archive for
15 * more details.
18 /******************************************************************************
20 TODO:
21 Despite of IGA Card has advanced graphic acceleration,
22 initial version is almost dummy and does not support it.
23 Support for video modes and acceleration must be added
24 together with accelerated X-Windows driver implementation.
26 Most important thing at this moment is that we have working
27 JavaEngine1 console & X with new console interface.
29 ******************************************************************************/
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/errno.h>
34 #include <linux/string.h>
35 #include <linux/mm.h>
36 #include <linux/tty.h>
37 #include <linux/malloc.h>
38 #include <linux/vmalloc.h>
39 #include <linux/delay.h>
40 #include <linux/interrupt.h>
41 #include <linux/fb.h>
42 #include <linux/selection.h>
43 #include <linux/console.h>
44 #include <linux/init.h>
45 #include <linux/pci.h>
46 #include <linux/nvram.h>
47 #include <linux/kd.h>
48 #include <linux/vt_kern.h>
50 #include <asm/io.h>
52 #ifdef __sparc__
53 #include <asm/pbm.h>
54 #include <asm/pcic.h>
55 #endif
57 #include <video/fbcon.h>
58 #include <video/fbcon-cfb8.h>
59 #include <video/fbcon-cfb16.h>
60 #include <video/fbcon-cfb24.h>
61 #include <video/fbcon-cfb32.h>
63 #include "iga.h"
65 static char igafb_name[16] = "IGA 1682";
66 static char fontname[40] __initdata = { 0 };
68 struct pci_mmap_map {
69 unsigned long voff;
70 unsigned long poff;
71 unsigned long size;
72 unsigned long prot_flag;
73 unsigned long prot_mask;
76 struct fb_info_iga {
77 struct fb_info fb_info;
78 unsigned long frame_buffer_phys;
79 char *frame_buffer;
80 unsigned long io_base_phys;
81 unsigned long io_base;
82 u32 total_vram;
83 struct pci_mmap_map *mmap_map;
84 struct { u_short blue, green, red, pad; } palette[256];
85 int video_cmap_len;
86 int currcon;
87 struct display disp;
88 struct display_switch dispsw;
89 union {
90 #ifdef FBCON_HAS_CFB16
91 u16 cfb16[16];
92 #endif
93 #ifdef FBCON_HAS_CFB24
94 u32 cfb24[16];
95 #endif
96 #ifdef FBCON_HAS_CFB32
97 u32 cfb32[16];
98 #endif
99 } fbcon_cmap;
100 #ifdef __sparc__
101 u8 open;
102 u8 mmaped;
103 int vtconsole;
104 int consolecnt;
105 #endif
108 struct fb_var_screeninfo default_var = {
109 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
110 640, 480, 640, 480, 0, 0, 8, 0,
111 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
112 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
113 0, FB_VMODE_NONINTERLACED
116 #ifdef __sparc__
117 struct fb_var_screeninfo default_var_1024x768 __initdata = {
118 /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
119 1024, 768, 1024, 768, 0, 0, 8, 0,
120 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
121 0, 0, -1, -1, 0, 12699, 176, 16, 28, 1, 96, 3,
122 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
125 struct fb_var_screeninfo default_var_1152x900 __initdata = {
126 /* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */
127 1152, 900, 1152, 900, 0, 0, 8, 0,
128 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
129 0, 0, -1, -1, 0, 9091, 234, 24, 34, 3, 100, 3,
130 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
133 struct fb_var_screeninfo default_var_1280x1024 __initdata = {
134 /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
135 1280, 1024, 1280, 1024, 0, 0, 8, 0,
136 {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
137 0, 0, -1, -1, 0, 7408, 248, 16, 38, 1, 144, 3,
138 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
142 * Memory-mapped I/O functions for Sparc PCI
144 * On sparc we happen to access I/O with memory mapped functions too.
146 #define pci_inb(info, reg) readb(info->io_base+(reg))
147 #define pci_outb(info, val, reg) writeb(val, info->io_base+(reg))
149 static inline unsigned int iga_inb(struct fb_info_iga *info,
150 unsigned int reg, unsigned int idx )
152 pci_outb(info, idx, reg);
153 return pci_inb(info, reg + 1);
156 static inline void iga_outb(struct fb_info_iga *info, unsigned char val,
157 unsigned int reg, unsigned int idx )
159 pci_outb(info, idx, reg);
160 pci_outb(info, val, reg+1);
163 #endif /* __sparc__ */
166 * Very important functionality for the JavaEngine1 computer:
167 * make screen border black (usign special IGA registers)
169 static void iga_blank_border(struct fb_info_iga *info)
171 int i;
173 #if 0
175 * PROM does this for us, so keep this code as a reminder
176 * about required read from 0x3DA and writing of 0x20 in the end.
178 (void) pci_inb(info, 0x3DA); /* required for every access */
179 pci_outb(info, IGA_IDX_VGA_OVERSCAN, IGA_ATTR_CTL);
180 (void) pci_inb(info, IGA_ATTR_CTL+1);
181 pci_outb(info, 0x38, IGA_ATTR_CTL);
182 pci_outb(info, 0x20, IGA_ATTR_CTL); /* re-enable visual */
183 #endif
185 * This does not work as it was designed because the overscan
186 * color is looked up in the palette. Therefore, under X11
187 * overscan changes color.
189 for (i=0; i < 3; i++)
190 iga_outb(info, 0, IGA_EXT_CNTRL, IGA_IDX_OVERSCAN_COLOR + i);
195 * Frame buffer device API
198 static int igafb_update_var(int con, struct fb_info *info)
200 return 0;
203 static int igafb_get_fix(struct fb_fix_screeninfo *fix, int con,
204 struct fb_info *info)
206 struct fb_info_iga *fb = (struct fb_info_iga*)info;
208 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
209 strcpy(fix->id, igafb_name);
211 fix->smem_start = (unsigned long) fb->frame_buffer;
212 fix->smem_len = fb->total_vram;
213 fix->xpanstep = 0;
214 fix->ypanstep = 0;
215 fix->ywrapstep = 0;
217 fix->type = FB_TYPE_PACKED_PIXELS;
218 fix->type_aux = 0;
219 fix->line_length = default_var.xres * (default_var.bits_per_pixel/8);
220 fix->visual = default_var.bits_per_pixel <= 8 ? FB_VISUAL_PSEUDOCOLOR
221 : FB_VISUAL_DIRECTCOLOR;
222 return 0;
225 static int igafb_get_var(struct fb_var_screeninfo *var, int con,
226 struct fb_info *info)
228 if(con == -1)
229 memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
230 else
231 *var = fb_display[con].var;
232 return 0;
235 static int igafb_set_var(struct fb_var_screeninfo *var, int con,
236 struct fb_info *info)
238 memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
239 return 0;
242 #ifdef __sparc__
243 static int igafb_mmap(struct fb_info *info, struct file *file,
244 struct vm_area_struct *vma)
246 struct fb_info_iga *fb = (struct fb_info_iga *)info;
247 unsigned int size, page, map_size = 0;
248 unsigned long map_offset = 0;
249 int i;
251 if (!fb->mmap_map)
252 return -ENXIO;
254 size = vma->vm_end - vma->vm_start;
256 /* To stop the swapper from even considering these pages. */
257 vma->vm_flags |= (VM_SHM | VM_LOCKED);
259 /* Each page, see which map applies */
260 for (page = 0; page < size; ) {
261 map_size = 0;
262 for (i = 0; fb->mmap_map[i].size; i++) {
263 unsigned long start = fb->mmap_map[i].voff;
264 unsigned long end = start + fb->mmap_map[i].size;
265 unsigned long offset = (vma->vm_pgoff << PAGE_SHIFT) + page;
267 if (start > offset)
268 continue;
269 if (offset >= end)
270 continue;
272 map_size = fb->mmap_map[i].size - (offset - start);
273 map_offset = fb->mmap_map[i].poff + (offset - start);
274 break;
276 if (!map_size) {
277 page += PAGE_SIZE;
278 continue;
280 if (page + map_size > size)
281 map_size = size - page;
283 pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
284 pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
286 if (remap_page_range(vma->vm_start + page, map_offset,
287 map_size, vma->vm_page_prot))
288 return -EAGAIN;
290 page += map_size;
293 if (!map_size)
294 return -EINVAL;
296 vma->vm_flags |= VM_IO;
298 if (!fb->mmaped) {
299 int lastconsole = 0;
301 if (info->display_fg)
302 lastconsole = info->display_fg->vc_num;
303 fb->mmaped = 1;
304 if (fb->consolecnt && fb_display[lastconsole].fb_info ==info) {
305 fb->vtconsole = lastconsole;
306 vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
309 return 0;
311 #endif /* __sparc__ */
314 static int iga_getcolreg(unsigned regno, unsigned *red, unsigned *green,
315 unsigned *blue, unsigned *transp,
316 struct fb_info *fb_info)
319 * Read a single color register and split it into colors/transparent.
320 * Return != 0 for invalid regno.
322 struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
324 if (regno >= info->video_cmap_len)
325 return 1;
327 *red = info->palette[regno].red;
328 *green = info->palette[regno].green;
329 *blue = info->palette[regno].blue;
330 *transp = 0;
331 return 0;
334 static int iga_setcolreg(unsigned regno, unsigned red, unsigned green,
335 unsigned blue, unsigned transp,
336 struct fb_info *fb_info)
339 * Set a single color register. The values supplied are
340 * already rounded down to the hardware's capabilities
341 * (according to the entries in the `var' structure). Return
342 * != 0 for invalid regno.
345 struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
347 if (regno >= info->video_cmap_len)
348 return 1;
350 info->palette[regno].red = red;
351 info->palette[regno].green = green;
352 info->palette[regno].blue = blue;
354 pci_outb(info, regno, DAC_W_INDEX);
355 pci_outb(info, red, DAC_DATA);
356 pci_outb(info, green, DAC_DATA);
357 pci_outb(info, blue, DAC_DATA);
359 if (regno < 16) {
360 switch (default_var.bits_per_pixel) {
361 #ifdef FBCON_HAS_CFB16
362 case 16:
363 info->fbcon_cmap.cfb16[regno] =
364 (regno << 10) | (regno << 5) | regno;
365 break;
366 #endif
367 #ifdef FBCON_HAS_CFB24
368 case 24:
369 info->fbcon_cmap.cfb24[regno] =
370 (regno << 16) | (regno << 8) | regno;
371 break;
372 #endif
373 #ifdef FBCON_HAS_CFB32
374 case 32:
375 { int i;
376 i = (regno << 8) | regno;
377 info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
379 break;
380 #endif
383 return 0;
386 static void do_install_cmap(int con, struct fb_info *fb_info)
388 struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
390 if (con != info->currcon)
391 return;
392 if (fb_display[con].cmap.len)
393 fb_set_cmap(&fb_display[con].cmap, 1,
394 iga_setcolreg, &info->fb_info);
395 else
396 fb_set_cmap(fb_default_cmap(info->video_cmap_len), 1,
397 iga_setcolreg, &info->fb_info);
400 static int igafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
401 struct fb_info *fb_info)
403 struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
405 if (con == info->currcon) /* current console? */
406 return fb_get_cmap(cmap, kspc, iga_getcolreg, &info->fb_info);
407 else if (fb_display[con].cmap.len) /* non default colormap? */
408 fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
409 else
410 fb_copy_cmap(fb_default_cmap(info->video_cmap_len),
411 cmap, kspc ? 0 : 2);
412 return 0;
415 static int igafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
416 struct fb_info *info)
418 int err;
419 struct fb_info_iga *fb = (struct fb_info_iga*) info;
421 if (!fb_display[con].cmap.len) { /* no colormap allocated? */
422 err = fb_alloc_cmap(&fb_display[con].cmap,
423 fb->video_cmap_len,0);
424 if (err)
425 return err;
427 if (con == fb->currcon) /* current console? */
428 return fb_set_cmap(cmap, kspc, iga_setcolreg, info);
429 else
430 fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
431 return 0;
435 * Framebuffer option structure
437 static struct fb_ops igafb_ops = {
438 owner: THIS_MODULE,
439 fb_get_fix: igafb_get_fix,
440 fb_get_var: igafb_get_var,
441 fb_set_var: igafb_set_var,
442 fb_get_cmap: igafb_get_cmap,
443 fb_set_cmap: igafb_set_cmap,
444 #ifdef __sparc__
445 fb_mmap: igafb_mmap,
446 #endif
449 static void igafb_set_disp(int con, struct fb_info_iga *info)
451 struct fb_fix_screeninfo fix;
452 struct display *display;
453 struct display_switch *sw;
455 if (con >= 0)
456 display = &fb_display[con];
457 else
458 display = &info->disp; /* used during initialization */
460 igafb_get_fix(&fix, con, &info->fb_info);
462 memset(display, 0, sizeof(struct display));
463 display->screen_base = info->frame_buffer;
464 display->visual = fix.visual;
465 display->type = fix.type;
466 display->type_aux = fix.type_aux;
467 display->ypanstep = fix.ypanstep;
468 display->ywrapstep = fix.ywrapstep;
469 display->line_length = fix.line_length;
470 display->next_line = fix.line_length;
471 display->can_soft_blank = 0;
472 display->inverse = 0;
473 igafb_get_var(&display->var, -1, &info->fb_info);
475 switch (default_var.bits_per_pixel) {
476 #ifdef FBCON_HAS_CFB8
477 case 8:
478 sw = &fbcon_cfb8;
479 break;
480 #endif
481 #ifdef FBCON_HAS_CFB16
482 case 15:
483 case 16:
484 sw = &fbcon_cfb16;
485 display->dispsw_data = info->fbcon_cmap.cfb16;
486 break;
487 #endif
488 #ifdef FBCON_HAS_CFB24
489 case 24:
490 sw = &fbcon_cfb24;
491 display->dispsw_data = info->fbcon_cmap.cfb24;
492 break;
493 #endif
494 #ifdef FBCON_HAS_CFB32
495 case 32:
496 sw = &fbcon_cfb32;
497 display->dispsw_data = info->fbcon_cmap.cfb32;
498 break;
499 #endif
500 default:
501 printk(KERN_WARNING "igafb_set_disp: unknown resolution %d\n",
502 default_var.bits_per_pixel);
503 return;
505 memcpy(&info->dispsw, sw, sizeof(*sw));
506 display->dispsw = &info->dispsw;
508 display->scrollmode = SCROLL_YREDRAW;
509 info->dispsw.bmove = fbcon_redraw_bmove;
512 static int igafb_switch(int con, struct fb_info *fb_info)
514 struct fb_info_iga *info = (struct fb_info_iga*) fb_info;
516 /* Do we have to save the colormap? */
517 if (fb_display[info->currcon].cmap.len)
518 fb_get_cmap(&fb_display[info->currcon].cmap, 1,
519 iga_getcolreg, fb_info);
521 info->currcon = con;
522 /* Install new colormap */
523 do_install_cmap(con, fb_info);
524 igafb_update_var(con, fb_info);
525 return 1;
530 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
532 static void igafb_blank(int blank, struct fb_info *info)
534 /* Not supported */
538 static int __init iga_init(struct fb_info_iga *info)
540 char vramsz = iga_inb(info, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL)
541 & MEM_SIZE_ALIAS;
542 switch (vramsz) {
543 case MEM_SIZE_1M:
544 info->total_vram = 0x100000;
545 break;
546 case MEM_SIZE_2M:
547 info->total_vram = 0x200000;
548 break;
549 case MEM_SIZE_4M:
550 case MEM_SIZE_RESERVED:
551 info->total_vram = 0x400000;
552 break;
555 if (default_var.bits_per_pixel > 8) {
556 info->video_cmap_len = 16;
557 } else {
558 info->video_cmap_len = 256;
561 int j, k;
562 for (j = 0; j < 16; j++) {
563 k = color_table[j];
564 info->palette[j].red = default_red[k];
565 info->palette[j].green = default_grn[k];
566 info->palette[j].blue = default_blu[k];
570 strcpy(info->fb_info.modename, igafb_name);
571 info->fb_info.node = -1;
572 info->fb_info.fbops = &igafb_ops;
573 info->fb_info.disp = &info->disp;
574 strcpy(info->fb_info.fontname, fontname);
575 info->fb_info.changevar = NULL;
576 info->fb_info.switch_con = &igafb_switch;
577 info->fb_info.updatevar = &igafb_update_var;
578 info->fb_info.blank = &igafb_blank;
579 info->fb_info.flags=FBINFO_FLAG_DEFAULT;
581 igafb_set_disp(-1, info);
583 if (register_framebuffer(&info->fb_info) < 0)
584 return 0;
586 printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n",
587 GET_FB_IDX(info->fb_info.node), igafb_name,
588 info->frame_buffer_phys, info->total_vram >> 20);
590 iga_blank_border(info);
591 return 1;
594 int __init igafb_init(void)
596 struct pci_dev *pdev;
597 struct fb_info_iga *info;
598 unsigned long addr;
599 extern int con_is_present(void);
600 int iga2000 = 0;
602 /* Do not attach when we have a serial console. */
603 if (!con_is_present())
604 return -ENXIO;
606 pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
607 PCI_DEVICE_ID_INTERG_1682, 0);
608 if (pdev == NULL) {
610 * XXX We tried to use cyber2000fb.c for IGS 2000.
611 * But it does not initialize the chip in JavaStation-E, alas.
613 pdev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, 0);
614 if(pdev == NULL) {
615 return -ENXIO;
617 iga2000 = 1;
620 info = kmalloc(sizeof(struct fb_info_iga), GFP_ATOMIC);
621 if (!info) {
622 printk("igafb_init: can't alloc fb_info_iga\n");
623 return -ENOMEM;
625 memset(info, 0, sizeof(struct fb_info_iga));
627 if ((addr = pdev->resource[0].start) == 0) {
628 printk("igafb_init: no memory start\n");
629 kfree(info);
630 return -ENXIO;
633 if ((info->frame_buffer = ioremap(addr, 1024*1024*2)) == 0) {
634 printk("igafb_init: can't remap %lx[2M]\n", addr);
635 kfree(info);
636 return -ENXIO;
639 info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
641 #ifdef __sparc__
643 * The following is sparc specific and this is why:
645 * IGS2000 has its I/O memory mapped and we want
646 * to generate memory cycles on PCI, e.g. do ioremap(),
647 * then readb/writeb() as in Documentation/IO-mapping.txt.
649 * IGS1682 is more traditional, it responds to PCI I/O
650 * cycles, so we want to access it with inb()/outb().
652 * On sparc, PCIC converts CPU memory access within
653 * phys window 0x3000xxxx into PCI I/O cycles. Therefore
654 * we may use readb/writeb to access them with IGS1682.
656 * We do not take io_base_phys from resource[n].start
657 * on IGS1682 because that chip is BROKEN. It does not
658 * have a base register for I/O. We just "know" what its
659 * I/O addresses are.
661 if (iga2000) {
662 info->io_base_phys = info->frame_buffer_phys | 0x00800000;
663 } else {
664 info->io_base_phys = 0x30000000; /* XXX */
666 if ((info->io_base = (int) ioremap(info->io_base_phys, 0x1000)) == 0) {
667 printk("igafb_init: can't remap %lx[4K]\n", info->io_base_phys);
668 iounmap((void *)info->frame_buffer);
669 kfree(info);
670 return -ENXIO;
674 * Figure mmap addresses from PCI config space.
675 * We need two regions: for video memory and for I/O ports.
676 * Later one can add region for video coprocessor registers.
677 * However, mmap routine loops until size != 0, so we put
678 * one additional region with size == 0.
681 info->mmap_map = kmalloc(4 * sizeof(*info->mmap_map), GFP_ATOMIC);
682 if (!info->mmap_map) {
683 printk("igafb_init: can't alloc mmap_map\n");
684 iounmap((void *)info->io_base);
685 iounmap(info->frame_buffer);
686 kfree(info);
687 return -ENOMEM;
690 memset(info->mmap_map, 0, 4 * sizeof(*info->mmap_map));
693 * Set default vmode and cmode from PROM properties.
696 struct pcidev_cookie *cookie = pdev->sysdata;
697 int node = cookie->prom_node;
698 int width = prom_getintdefault(node, "width", 1024);
699 int height = prom_getintdefault(node, "height", 768);
700 int depth = prom_getintdefault(node, "depth", 8);
701 switch (width) {
702 case 1024:
703 if (height == 768)
704 default_var = default_var_1024x768;
705 break;
706 case 1152:
707 if (height == 900)
708 default_var = default_var_1152x900;
709 break;
710 case 1280:
711 if (height == 1024)
712 default_var = default_var_1280x1024;
713 break;
714 default:
715 break;
718 switch (depth) {
719 case 8:
720 default_var.bits_per_pixel = 8;
721 break;
722 case 16:
723 default_var.bits_per_pixel = 16;
724 break;
725 case 24:
726 default_var.bits_per_pixel = 24;
727 break;
728 case 32:
729 default_var.bits_per_pixel = 32;
730 break;
731 default:
732 break;
736 #endif
738 if (!iga_init(info)) {
739 iounmap((void *)info->io_base);
740 iounmap(info->frame_buffer);
741 if (info->mmap_map)
742 kfree(info->mmap_map);
743 kfree(info);
746 #ifdef __sparc__
748 * Add /dev/fb mmap values.
751 /* First region is for video memory */
752 info->mmap_map[0].voff = 0x0;
753 info->mmap_map[0].poff = info->frame_buffer_phys & PAGE_MASK;
754 info->mmap_map[0].size = info->total_vram & PAGE_MASK;
755 info->mmap_map[0].prot_mask = SRMMU_CACHE;
756 info->mmap_map[0].prot_flag = SRMMU_WRITE;
758 /* Second region is for I/O ports */
759 info->mmap_map[1].voff = info->frame_buffer_phys & PAGE_MASK;
760 info->mmap_map[1].poff = info->io_base_phys & PAGE_MASK;
761 info->mmap_map[1].size = PAGE_SIZE * 2; /* X wants 2 pages */
762 info->mmap_map[1].prot_mask = SRMMU_CACHE;
763 info->mmap_map[1].prot_flag = SRMMU_WRITE;
764 #endif /* __sparc__ */
766 return 0;
769 int __init igafb_setup(char *options)
771 char *this_opt;
773 if (!options || !*options)
774 return 0;
776 for (this_opt = strtok(options, ","); this_opt;
777 this_opt = strtok(NULL, ",")) {
778 if (!strncmp(this_opt, "font:", 5)) {
779 char *p;
780 int i;
782 p = this_opt + 5;
783 for (i = 0; i < sizeof(fontname) - 1; i++)
784 if (!*p || *p == ' ' || *p == ',')
785 break;
786 memcpy(fontname, this_opt + 5, i);
787 fontname[i] = 0;
790 return 0;