From: M. R. B. <mr...@us...> - 2002-10-29 15:20:24
|
Update of /cvsroot/linuxdc/linux-sh-dc/drivers/video In directory usw-pr-cvs1:/tmp/cvs-serv9028/drivers/video Modified Files: pvr2fb.c Log Message: Linux-SH 2.5.44 switchover Index: pvr2fb.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/drivers/video/pvr2fb.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- pvr2fb.c 23 Jan 2002 06:56:48 -0000 1.6 +++ pvr2fb.c 29 Oct 2002 15:20:21 -0000 1.7 @@ -4,7 +4,7 @@ * Dreamcast. * * Copyright (c) 2001 M. R. Brown <mr...@0x...> - * Copyright (c) 2001 Paul Mundt <le...@ch...> + * Copyright (c) 2001, 2002 Paul Mundt <le...@li...> * * This file is part of the LinuxDC project (linuxdc.sourceforge.net). * @@ -12,14 +12,15 @@ /* * This driver is mostly based on the excellent amifb and vfb sources. It uses - * an odd scheme for converting hardware values to/from framebuffer values, here are - * some hacked-up formulas: + * an odd scheme for converting hardware values to/from framebuffer values, + * here are some hacked-up formulas: * - * The Dreamcast has screen offsets from each side of it's four borders and the start - * offsets of the display window. I used these values to calculate 'pseudo' values - * (think of them as placeholders) for the fb video mode, so that when it came time - * to convert these values back into their hardware values, I could just add mode- - * specific offsets to get the correct mode settings: + * The Dreamcast has screen offsets from each side of it's four borders and + * the start offsets of the display window. I used these values to calculate + * 'pseudo' values (think of them as placeholders) for the fb video mode, so + * that when it came time to convert these values back into their hardware + * values, I could just add mode- specific offsets to get the correct mode + * settings: * * left_margin = diwstart_h - borderstart_h; * right_margin = borderstop_h - (diwstart_h + xres); @@ -29,9 +30,9 @@ * hsync_len = borderstart_h + (hsync_total - borderstop_h); * vsync_len = borderstart_v + (vsync_total - borderstop_v); * - * Then, when it's time to convert back to hardware settings, the only constants - * are the borderstart_* offsets, all other values are derived from the fb video - * mode: + * Then, when it's time to convert back to hardware settings, the only + * constants are the borderstart_* offsets, all other values are derived from + * the fb video mode: * * // PAL * borderstart_h = 116; @@ -157,10 +158,8 @@ } currentpar; -static int currcon = 0; static int currbpp; -static struct display disp; -static struct fb_info fb_info; +static struct fb_info *fb_info; static int pvr2fb_inverse = 0; static struct { u_short red, green, blue, alpha; } palette[256]; @@ -176,7 +175,29 @@ #endif } fbcon_cmap; -static char pvr2fb_name[16] = "NEC PowerVR2"; +static struct fb_fix_screeninfo pvr2_fix __initdata = { + .id = "NEC PowerVR2", + .type = FB_TYPE_PACKED_PIXELS, + .visual = FB_VISUAL_TRUECOLOR, + .ypanstep = 1, + .ywrapstep = 1, + .accel = FB_ACCEL_NONE, +}; + +static struct fb_var_screeninfo pvr2_var __initdata = { + .xres = 640, + .yres = 480, + .xres_virtual = 640, + .yres_virtual = 480, + .bits_per_pixel =16, + .red = { 11, 5, 0 }, + .green = { 5, 6, 0 }, + .blue = { 0, 5, 0 }, + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, +}; #define VIDEOMEMSIZE (8*1024*1024) static u_long videomemory = 0xa5000000, videomemorysize = VIDEOMEMSIZE; @@ -188,6 +209,9 @@ static int mtrr_handle; #endif +static int nopan = 0; +static int nowrap = 1; + /* * We do all updating, blanking, etc. during the vertical retrace period */ @@ -202,49 +226,13 @@ int pvr2fb_setup(char*); -static int pvr2fb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info); -static int pvr2fb_get_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info); -static int pvr2fb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info); -static int pvr2fb_pan_display(struct fb_var_screeninfo *var, int con, - struct fb_info *info); -static int pvr2fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info); -static int pvr2fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info); - - /* - * Interface to the low level console driver - */ - -static int pvr2fbcon_switch(int con, struct fb_info *info); -static int pvr2fbcon_updatevar(int con, struct fb_info *info); -static void pvr2fbcon_blank(int blank, struct fb_info *info); - - /* - * Internal/hardware-specific routines - */ - -static void do_install_cmap(int con, struct fb_info *info); +static int pvr2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, + u_int transp, struct fb_info *info); +static int pvr2fb_blank(int blank, struct fb_info *info); static u_long get_line_length(int xres_virtual, int bpp); static void set_color_bitfields(struct fb_var_screeninfo *var); -static int pvr2_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp, struct fb_info *info); -static int pvr2_setcolreg(u_int regno, u_int red, u_int green, u_int blue, - u_int transp, struct fb_info *info); - -static int pvr2_encode_fix(struct fb_fix_screeninfo *fix, - struct pvr2fb_par *par); -static int pvr2_decode_var(struct fb_var_screeninfo *var, - struct pvr2fb_par *par); -static int pvr2_encode_var(struct fb_var_screeninfo *var, - struct pvr2fb_par *par); -static void pvr2_get_par(struct pvr2fb_par *par); -static void pvr2_set_var(struct fb_var_screeninfo *var); -static void pvr2_pan_var(struct fb_var_screeninfo *var); -static int pvr2_update_par(void); +static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); +static int pvr2fb_set_par(struct fb_info *info); static void pvr2_update_display(void); static void pvr2_init_display(void); static void pvr2_do_blank(void); @@ -254,17 +242,14 @@ int val, int size); static struct fb_ops pvr2fb_ops = { - owner: THIS_MODULE, - fb_get_fix: pvr2fb_get_fix, - fb_get_var: pvr2fb_get_var, - fb_set_var: pvr2fb_set_var, - fb_get_cmap: pvr2fb_get_cmap, - fb_set_cmap: pvr2fb_set_cmap, - fb_pan_display: pvr2fb_pan_display, + .owner = THIS_MODULE, + .fb_setcolreg = pvr2fb_setcolreg, + .fb_blank = pvr2fb_blank, + .fb_check_var = pvr2fb_check_var, + .fb_set_par = pvr2fb_set_par, }; static struct fb_videomode pvr2_modedb[] __initdata = { - /* * Broadcast video modes (PAL and NTSC). I'm unfamiliar with * PAL-M and PAL-N, but from what I've read both modes parallel PAL and @@ -275,21 +260,16 @@ /* 640x480 @ 60Hz interlaced (NTSC) */ "ntsc_640x480i", 60, 640, 480, TV_CLK, 38, 33, 0, 18, 146, 26, FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP - }, - - { + }, { /* 640x240 @ 60Hz (NTSC) */ /* XXX: Broken! Don't use... */ "ntsc_640x240", 60, 640, 240, TV_CLK, 38, 33, 0, 0, 146, 22, FB_SYNC_BROADCAST, FB_VMODE_YWRAP - }, - - { + }, { /* 640x480 @ 60hz (VGA) */ "vga_640x480", 60, 640, 480, VGA_CLK, 38, 33, 0, 18, 146, 26, 0, FB_VMODE_YWRAP }, - }; #define NUM_TOTAL_MODES ARRAY_SIZE(pvr2_modedb) @@ -301,236 +281,11 @@ static int defmode = DEFMODE_NTSC; static char *mode_option __initdata = NULL; -/* Get the fixed part of the display */ - -static int pvr2fb_get_fix(struct fb_fix_screeninfo *fix, int con, - struct fb_info *info) -{ - struct pvr2fb_par par; - - if (con == -1) - pvr2_get_par(&par); - else { - int err; - - if ((err = pvr2_decode_var(&fb_display[con].var, &par))) - return err; - } - return pvr2_encode_fix(fix, &par); -} - -/* Get the user-defined part of the display */ - -static int pvr2fb_get_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - int err = 0; - - if (con == -1) { - struct pvr2fb_par par; - - pvr2_get_par(&par); - err = pvr2_encode_var(var, &par); - } else - *var = fb_display[con].var; - - return err; -} - -/* Set the user-defined part of the display */ - -static int pvr2fb_set_var(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - int err, activate = var->activate; - int oldxres, oldyres, oldvxres, oldvyres, oldbpp; - struct pvr2fb_par par; - - struct display *display; - if (con >= 0) - display = &fb_display[con]; - else - display = &disp; /* used during initialization */ - - /* - * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! - * as FB_VMODE_SMOOTH_XPAN is only used internally - */ - - if (var->vmode & FB_VMODE_CONUPDATE) { - var->vmode |= FB_VMODE_YWRAP; - var->xoffset = display->var.xoffset; - var->yoffset = display->var.yoffset; - } - if ((err = pvr2_decode_var(var, &par))) - return err; - pvr2_encode_var(var, &par); - - /* Do memory check and bitfield set here?? */ - - if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { - oldxres = display->var.xres; - oldyres = display->var.yres; - oldvxres = display->var.xres_virtual; - oldvyres = display->var.yres_virtual; - oldbpp = display->var.bits_per_pixel; - display->var = *var; - if (oldxres != var->xres || oldyres != var->yres || - oldvxres != var->xres_virtual || oldvyres != var->yres_virtual || - oldbpp != var->bits_per_pixel) { - struct fb_fix_screeninfo fix; - - pvr2_encode_fix(&fix, &par); - display->screen_base = (char *)fix.smem_start; - display->scrollmode = SCROLL_YREDRAW; - display->visual = fix.visual; - display->type = fix.type; - display->type_aux = fix.type_aux; - display->ypanstep = fix.ypanstep; - display->ywrapstep = fix.ywrapstep; - display->line_length = fix.line_length; - display->can_soft_blank = 1; - display->inverse = pvr2fb_inverse; - switch (var->bits_per_pixel) { -#ifdef FBCON_HAS_CFB16 - case 16: - display->dispsw = &fbcon_cfb16; - display->dispsw_data = fbcon_cmap.cfb16; - break; -#endif -#ifdef FBCON_HAS_CFB24 - case 24: - display->dispsw = &fbcon_cfb24; - display->dispsw_data = fbcon_cmap.cfb24; - break; -#endif -#ifdef FBCON_HAS_CFB32 - case 32: - display->dispsw = &fbcon_cfb32; - display->dispsw_data = fbcon_cmap.cfb32; - break; -#endif - default: - display->dispsw = &fbcon_dummy; - break; - } - if (fb_info.changevar) - (*fb_info.changevar)(con); - } - if (oldbpp != var->bits_per_pixel) { - if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) - return err; - do_install_cmap(con, info); - } - if (con == currcon) - pvr2_set_var(&display->var); - } - - return 0; -} - -/* - * Pan or wrap the display. - * This call looks only at xoffset, yoffset and the FB_VMODE_YRAP flag - */ - -static int pvr2fb_pan_display(struct fb_var_screeninfo *var, int con, - struct fb_info *info) -{ - if (var->vmode & FB_VMODE_YWRAP) { - if (var->yoffset<0 || var->yoffset >= - fb_display[con].var.yres_virtual || var->xoffset) - return -EINVAL; - } else { - if (var->xoffset+fb_display[con].var.xres > - fb_display[con].var.xres_virtual || - var->yoffset+fb_display[con].var.yres > - fb_display[con].var.yres_virtual) - return -EINVAL; - } - if (con == currcon) - pvr2_pan_var(var); - fb_display[con].var.xoffset = var->xoffset; - fb_display[con].var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - fb_display[con].var.vmode |= FB_VMODE_YWRAP; - else - fb_display[con].var.vmode &= ~FB_VMODE_YWRAP; - - return 0; -} - -/* Get the colormap */ - -static int pvr2fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info) -{ - if (con == currcon) /* current console? */ - return fb_get_cmap(cmap, kspc, pvr2_getcolreg, info); - else if (fb_display[con].cmap.len) /* non default colormap? */ - fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); - else - fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), - cmap, kspc ? 0 : 2); - return 0; -} - -/* Set the colormap */ - -static int pvr2fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, - struct fb_info *info) -{ - int err; - - if (!fb_display[con].cmap.len) { /* no colormap allocated? */ - if ((err = fb_alloc_cmap(&fb_display[con].cmap, - 1<<fb_display[con].var.bits_per_pixel, - 0))) - return err; - } - if (con == currcon) /* current console? */ - return fb_set_cmap(cmap, kspc, pvr2_setcolreg, info); - else - fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); - - return 0; -} - -static int pvr2fbcon_switch(int con, struct fb_info *info) -{ - /* Do we have to save the colormap? */ - if (fb_display[currcon].cmap.len) - fb_get_cmap(&fb_display[currcon].cmap, 1, pvr2_getcolreg, info); - - currcon = con; - pvr2_set_var(&fb_display[con].var); - /* Install new colormap */ - do_install_cmap(con, info); - return 0; -} - -static int pvr2fbcon_updatevar(int con, struct fb_info *info) -{ - pvr2_pan_var(&fb_display[con].var); - return 0; -} - -static void pvr2fbcon_blank(int blank, struct fb_info *info) +static int pvr2fb_blank(int blank, struct fb_info *info) { do_blank = blank ? blank : -1; -} - -/* Setup the colormap */ -static void do_install_cmap(int con, struct fb_info *info) -{ - if (con != currcon) - return; - if (fb_display[con].cmap.len) - fb_set_cmap(&fb_display[con].cmap, 1, pvr2_setcolreg, info); - else - fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), - 1, pvr2_setcolreg, info); + return 0; } static inline u_long get_line_length(int xres_virtual, int bpp) @@ -562,20 +317,7 @@ } } -static int pvr2_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, - u_int *transp, struct fb_info *info) -{ - if (regno > 255) - return 1; - - *red = palette[regno].red; - *green = palette[regno].green; - *blue = palette[regno].blue; - *transp = 0; - return 0; -} - -static int pvr2_setcolreg(u_int regno, u_int red, u_int green, u_int blue, +static int pvr2fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info) { if (regno > 255) @@ -615,39 +357,10 @@ return 0; } - -static int pvr2_encode_fix(struct fb_fix_screeninfo *fix, - struct pvr2fb_par *par) -{ - memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - strcpy(fix->id, pvr2fb_name); - fix->smem_start = videomemory; - fix->smem_len = videomemorysize; - fix->type = FB_TYPE_PACKED_PIXELS; - fix->type_aux = 0; - fix->visual = FB_VISUAL_TRUECOLOR; - - if (par->vmode & FB_VMODE_YWRAP) { - fix->ywrapstep = 1; - fix->xpanstep = fix->ypanstep = 0; - } else { - fix->ywrapstep = 0; - fix->xpanstep = 1; - fix->ypanstep = 1; - } - fix->line_length = par->next_line; - - return 0; -} - -/* - * Create a hardware video mode using the framebuffer values. If a value needs - * to be clipped or constrained it's done here. This routine needs a bit more - * work to make sure we're doing the right tests at the right time. - */ -static int pvr2_decode_var(struct fb_var_screeninfo *var, - struct pvr2fb_par *par) +static int pvr2fb_set_par(struct fb_info *info) { + struct pvr2fb_par *par = (struct pvr2fb_par *)info->par; + struct fb_var_screeninfo *var = &info->var; u_long line_length; u_short vtotal; @@ -677,10 +390,10 @@ /* * XXX: It's possible that a user could use a VGA box, change the cable - * type in hardware (i.e. switch from VGA<->composite), then change modes - * (i.e. switching to another VT). If that happens we should automagically - * change the output format to cope, but currently I don't have a VGA box - * to make sure this works properly. + * type in hardware (i.e. switch from VGA<->composite), then change + * modes (i.e. switching to another VT). If that happens we should + * automagically change the output format to cope, but currently I + * don't have a VGA box to make sure this works properly. */ cable_type = pvr2_init_cable(); if (cable_type == CT_VGA && video_output != VO_VGA) @@ -728,8 +441,8 @@ /* VGA mode */ /* XXX: What else needs to be checked? */ /* - * XXX: We have a little freedom in VGA modes, what ranges should - * be here (i.e. hsync/vsync totals, etc.)? + * XXX: We have a little freedom in VGA modes, what ranges + * should be here (i.e. hsync/vsync totals, etc.)? */ par->borderstart_h = 126; par->borderstart_v = 40; @@ -742,9 +455,9 @@ var->vsync_len; par->diwstart_h = par->borderstart_h + var->left_margin; par->diwstart_v = par->borderstart_v + var->upper_margin; + if (!par->is_interlaced) par->borderstop_v /= 2; - if (par->xres < 640) par->is_lowres = 1; @@ -775,10 +488,9 @@ return 0; } -static int pvr2_encode_var(struct fb_var_screeninfo *var, - struct pvr2fb_par *par) +static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - memset(var, 0, sizeof(struct fb_var_screeninfo)); + struct pvr2fb_par *par = (struct pvr2fb_par *)info->par; var->xres = par->xres; var->yres = par->yres; @@ -791,8 +503,6 @@ set_color_bitfields(var); var->activate = FB_ACTIVATE_NOW; - var->height = -1; - var->width = -1; var->pixclock = par->pixclock; @@ -819,56 +529,6 @@ return 0; } -static void pvr2_get_par(struct pvr2fb_par *par) -{ - *par = currentpar; -} - -/* Setup the new videomode in hardware */ - -static void pvr2_set_var(struct fb_var_screeninfo *var) -{ - do_vmode_pan = 0; - do_vmode_full = 0; - pvr2_decode_var(var, ¤tpar); - - do_vmode_full = 1; -} - -/* - * Pan or wrap the display - * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag in `var'. - */ -static void pvr2_pan_var(struct fb_var_screeninfo *var) -{ - struct pvr2fb_par *par = ¤tpar; - - par->xoffset = var->xoffset; - par->yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - par->vmode |= FB_VMODE_YWRAP; - else - par->vmode &= ~FB_VMODE_YWRAP; - - do_vmode_pan = 0; - pvr2_update_par(); - do_vmode_pan = 1; -} - -static int pvr2_update_par(void) -{ - struct pvr2fb_par *par = ¤tpar; - u_long move; - - move = get_line_length(par->xoffset, par->bpp); - if (par->yoffset) { - par->disp_start += (par->next_line * par->yoffset) + move; - } else - par->disp_start += move; - - return 0; -} - static void pvr2_update_display(void) { struct pvr2fb_par *par = ¤tpar; @@ -933,7 +593,6 @@ /* video enable, color sync, interlace, * hsync and vsync polarity (currently unused) */ ctrl_outl(0x100 | ((par->is_interlaced /*|4*/) << 4), DISP_SYNCCONF); - } /* Simulate blanking by making the border cover the entire screen */ @@ -957,21 +616,16 @@ { if (do_vmode_pan || do_vmode_full) pvr2_update_display(); - if (do_vmode_full) pvr2_init_display(); - if (do_vmode_pan) do_vmode_pan = 0; - + if (do_vmode_full) + do_vmode_full = 0; if (do_blank) { pvr2_do_blank(); do_blank = 0; } - - if (do_vmode_full) { - do_vmode_full = 0; - } } /* @@ -1010,50 +664,88 @@ if (!MACH_DREAMCAST) return -ENXIO; + fb_info = kmalloc(sizeof(struct fb_info) + sizeof(struct display) + + sizeof(u32) * 16, GFP_KERNEL); + + if (!fb_info) { + printk(KERN_ERR "Failed to allocate memory for fb_info\n"); + return -ENOMEM; + } + + memset(fb_info, 0, sizeof(fb_info) + sizeof(struct display) + sizeof(u32) * 16); + /* Make a guess at the monitor based on the attached cable */ if (pvr2_init_cable() == CT_VGA) { - fb_info.monspecs.hfmin = 30000; - fb_info.monspecs.hfmax = 70000; - fb_info.monspecs.vfmin = 60; - fb_info.monspecs.vfmax = 60; - } - else { /* Not VGA, using a TV (taken from acornfb) */ - fb_info.monspecs.hfmin = 15469; - fb_info.monspecs.hfmax = 15781; - fb_info.monspecs.vfmin = 49; - fb_info.monspecs.vfmax = 51; + fb_info->monspecs.hfmin = 30000; + fb_info->monspecs.hfmax = 70000; + fb_info->monspecs.vfmin = 60; + fb_info->monspecs.vfmax = 60; + } else { + /* Not VGA, using a TV (taken from acornfb) */ + fb_info->monspecs.hfmin = 15469; + fb_info->monspecs.hfmax = 15781; + fb_info->monspecs.vfmin = 49; + fb_info->monspecs.vfmax = 51; } - /* XXX: This needs to pull default video output via BIOS or other means */ + /* + * XXX: This needs to pull default video output via BIOS or other means + */ if (video_output < 0) { - if (cable_type == CT_VGA) + if (cable_type == CT_VGA) { video_output = VO_VGA; - else + } else { video_output = VO_NTSC; } + } + + pvr2_fix.smem_start = videomemory; + pvr2_fix.smem_len = videomemorysize; + + fb_info->screen_base = ioremap_nocache(pvr2_fix.smem_start, + pvr2_fix.smem_len); + + if (!fb_info->screen_base) { + printk("Failed to remap MMIO space\n"); + kfree(fb_info); + return -ENXIO; + } + + memset_io((unsigned long)fb_info->screen_base, 0, pvr2_fix.smem_len); + + pvr2_fix.ypanstep = nopan ? 0 : 1; + pvr2_fix.ywrapstep = nowrap ? 0 : 1; + + strcpy(fb_info->modename, fb_info->fix.id); + + fb_info->node = NODEV; + fb_info->fbops = &pvr2fb_ops; + fb_info->fix = pvr2_fix; + fb_info->par = ¤tpar; + fb_info->disp = (struct display *)(fb_info + 1); + fb_info->pseudo_palette = (void *)(fb_info->disp + 1); + fb_info->flags = FBINFO_FLAG_DEFAULT; + + fb_info->currcon = -1; + fb_info->switch_con = gen_switch; + fb_info->updatevar = gen_update_var; - strcpy(fb_info.modename, pvr2fb_name); - fb_info.changevar = NULL; - fb_info.node = -1; - fb_info.fbops = &pvr2fb_ops; - fb_info.disp = &disp; - fb_info.switch_con = &pvr2fbcon_switch; - fb_info.updatevar = &pvr2fbcon_updatevar; - fb_info.blank = &pvr2fbcon_blank; - fb_info.flags = FBINFO_FLAG_DEFAULT; memset(&var, 0, sizeof(var)); if (video_output == VO_VGA) defmode = DEFMODE_VGA; - if (!fb_find_mode(&var, &fb_info, mode_option, pvr2_modedb, - NUM_TOTAL_MODES, &pvr2_modedb[defmode], 16)) { - return -EINVAL; - } + if (!mode_option) + mode_option = "640x480@60"; - if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, SA_SHIRQ, + if (!fb_find_mode(&fb_info->var, fb_info, mode_option, pvr2_modedb, + NUM_TOTAL_MODES, &pvr2_modedb[defmode], 16)) + fb_info->var = pvr2_var; + + if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0, "pvr2 VBL handler", ¤tpar)) { DPRINTK("couldn't register VBL int\n"); + kfree(fb_info); return -EBUSY; } @@ -1064,18 +756,20 @@ } #endif - pvr2fb_set_var(&var, -1, &fb_info); + gen_set_var(&fb_info->var, -1, fb_info); - if (register_framebuffer(&fb_info) < 0) + if (register_framebuffer(fb_info) < 0) { + kfree(fb_info); return -EINVAL; + } modememused = get_line_length(var.xres_virtual, var.bits_per_pixel); modememused *= var.yres_virtual; printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n", - GET_FB_IDX(fb_info.node), fb_info.modename, modememused>>10, + GET_FB_IDX(fb_info->node), fb_info->modename, modememused>>10, videomemorysize>>10); printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", - GET_FB_IDX(fb_info.node), var.xres, var.yres, var.bits_per_pixel, + GET_FB_IDX(fb_info->node), var.xres, var.yres, var.bits_per_pixel, get_line_length(var.xres, var.bits_per_pixel), (char *)pvr2_get_param(cables, NULL, cable_type, 3), (char *)pvr2_get_param(outputs, NULL, video_output, 3)); @@ -1091,7 +785,8 @@ printk("pvr2fb: MTRR turned off\n"); } #endif - unregister_framebuffer(&fb_info); + unregister_framebuffer(fb_info); + kfree(fb_info); } static int __init pvr2_get_param(const struct pvr2_params *p, const char *s, @@ -1115,7 +810,6 @@ * Parse command arguments. Supported arguments are: * inverse Use inverse color maps * nomtrr Disable MTRR usage - * font:<fontname> Specify console font * cable:composite|rgb|vga Override the video cable type * output:NTSC|PAL|VGA Override the video output format * @@ -1130,8 +824,6 @@ char cable_arg[80]; char output_arg[80]; - fb_info.fontname[0] = '\0'; - if (!options || !*options) return 0; @@ -1141,23 +833,25 @@ if (!strcmp(this_opt, "inverse")) { pvr2fb_inverse = 1; fb_invert_cmaps(); - } else if (!strncmp(this_opt, "font:", 5)) - strcpy(fb_info.fontname, this_opt + 5); - else if (!strncmp(this_opt, "cable:", 6)) + } else if (!strncmp(this_opt, "cable:", 6)) { strcpy(cable_arg, this_opt + 6); - else if (!strncmp(this_opt, "output:", 7)) + } else if (!strncmp(this_opt, "output:", 7)) { strcpy(output_arg, this_opt + 7); + } else if (!strncmp(this_opt, "nopan", 5)) { + nopan = 1; + } else if (!strncmp(this_opt, "nowrap", 6)) { + nowrap = 1; #ifdef CONFIG_MTRR - else if (!strncmp(this_opt, "nomtrr", 6)) + } else if (!strncmp(this_opt, "nomtrr", 6)) { enable_mtrr = 0; #endif - else + } else { mode_option = this_opt; } + } if (*cable_arg) cable_type = pvr2_get_param(cables, cable_arg, 0, 3); - if (*output_arg) video_output = pvr2_get_param(outputs, output_arg, 0, 3); |