X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fvideo%2Fcirrusfb.c;h=4c16b68a9c5acd6cc0321cfbab6dbe5ec88cd262;hb=a1d35a7a50d01b445e29d87f479f8c055a414f7e;hp=dfd12a2dfe72a7dbc66ad0cdd7443129e41d6997;hpb=7528f543889fd460964b42881296b2e84457684e;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index dfd12a2..4c16b68 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -367,110 +367,13 @@ struct cirrusfb_info { struct cirrusfb_regs currentmode; int blank_mode; + u32 pseudo_palette[16]; - u32 pseudo_palette[16]; - -#ifdef CONFIG_ZORRO - struct zorro_dev *zdev; -#endif -#ifdef CONFIG_PCI - struct pci_dev *pdev; -#endif void (*unmap)(struct fb_info *info); }; -static unsigned cirrusfb_def_mode = 1; static int noaccel; - -/* - * Predefined Video Modes - */ - -static const struct { - const char *name; - struct fb_var_screeninfo var; -} cirrusfb_predefined[] = { - { - /* autodetect mode */ - .name = "Autodetect", - }, { - /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */ - .name = "640x480", - .var = { - .xres = 640, - .yres = 480, - .xres_virtual = 640, - .yres_virtual = 480, - .bits_per_pixel = 8, - .red = { .length = 8 }, - .green = { .length = 8 }, - .blue = { .length = 8 }, - .width = -1, - .height = -1, - .pixclock = 40000, - .left_margin = 48, - .right_margin = 16, - .upper_margin = 32, - .lower_margin = 8, - .hsync_len = 96, - .vsync_len = 4, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, - .vmode = FB_VMODE_NONINTERLACED - } - }, { - /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */ - .name = "800x600", - .var = { - .xres = 800, - .yres = 600, - .xres_virtual = 800, - .yres_virtual = 600, - .bits_per_pixel = 8, - .red = { .length = 8 }, - .green = { .length = 8 }, - .blue = { .length = 8 }, - .width = -1, - .height = -1, - .pixclock = 20000, - .left_margin = 128, - .right_margin = 16, - .upper_margin = 24, - .lower_margin = 2, - .hsync_len = 96, - .vsync_len = 6, - .vmode = FB_VMODE_NONINTERLACED - } - }, { - /* - * Modeline from XF86Config: - * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805 - */ - /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */ - .name = "1024x768", - .var = { - .xres = 1024, - .yres = 768, - .xres_virtual = 1024, - .yres_virtual = 768, - .bits_per_pixel = 8, - .red = { .length = 8 }, - .green = { .length = 8 }, - .blue = { .length = 8 }, - .width = -1, - .height = -1, - .pixclock = 12500, - .left_margin = 144, - .right_margin = 32, - .upper_margin = 30, - .lower_margin = 2, - .hsync_len = 192, - .vsync_len = 6, - .vmode = FB_VMODE_NONINTERLACED - } - } -}; - -#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined) +static char *mode_option __devinitdata = "640x480@60"; /****************************************************************************/ /**** BEGIN PROTOTYPES ******************************************************/ @@ -638,7 +541,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, break; /* 8 pixel per byte, only 1/4th of mem usable */ case 8: case 16: - case 24: case 32: break; /* 1 pixel == 1 byte */ default: @@ -713,7 +615,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var, var->blue.length = 5; break; - case 24: case 32: if (isPReP) { var->red.offset = 8; @@ -782,7 +683,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var, break; case 16: - case 24: case 32: info->fix.line_length = var->xres_virtual * maxclockidx; info->fix.visual = FB_VISUAL_DIRECTCOLOR; @@ -1360,7 +1260,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info) */ else if (var->bits_per_pixel == 32) { - DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n"); + DPRINTK("cirrusfb: preparing for 32 bit deep display\n"); switch (cinfo->btype) { case BT_SD64: /* Extended Sequencer Mode: 256c col. mode */ @@ -2186,8 +2086,7 @@ static void get_pci_addrs(const struct pci_dev *pdev, static void cirrusfb_pci_unmap(struct fb_info *info) { - struct cirrusfb_info *cinfo = info->par; - struct pci_dev *pdev = cinfo->pdev; + struct pci_dev *pdev = to_pci_dev(info->device); iounmap(info->screen_base); #if 0 /* if system didn't claim this region, we would... */ @@ -2203,14 +2102,16 @@ static void cirrusfb_pci_unmap(struct fb_info *info) static void __devexit cirrusfb_zorro_unmap(struct fb_info *info) { struct cirrusfb_info *cinfo = info->par; - zorro_release_device(cinfo->zdev); + struct zorro_dev *zdev = to_zorro_dev(info->device); + + zorro_release_device(zdev); if (cinfo->btype == BT_PICASSO4) { cinfo->regbase -= 0x600000; iounmap((void *)cinfo->regbase); iounmap(info->screen_base); } else { - if (zorro_resource_start(cinfo->zdev) > 0x01000000) + if (zorro_resource_start(zdev) > 0x01000000) iounmap(info->screen_base); } } @@ -2233,7 +2134,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info) if (cinfo->btype == BT_GD5480) { if (var->bits_per_pixel == 16) info->screen_base += 1 * MB_; - if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32) + if (var->bits_per_pixel == 32) info->screen_base += 2 * MB_; } @@ -2276,23 +2177,27 @@ static int cirrusfb_register(struct fb_info *info) /* sanity checks */ assert(btype != BT_NONE); + /* set all the vital stuff */ + cirrusfb_set_fbinfo(info); + DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base); - /* Make pretend we've set the var so our structures are in a "good" */ - /* state, even though we haven't written the mode to the hw yet... */ - info->var = cirrusfb_predefined[cirrusfb_def_mode].var; + err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); + if (!err) { + DPRINTK("wrong initial video mode\n"); + err = -EINVAL; + goto err_dealloc_cmap; + } + info->var.activate = FB_ACTIVATE_NOW; err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info); if (err < 0) { /* should never happen */ DPRINTK("choking on default var... umm, no good.\n"); - goto err_unmap_cirrusfb; + goto err_dealloc_cmap; } - /* set all the vital stuff */ - cirrusfb_set_fbinfo(info); - err = register_framebuffer(info); if (err < 0) { printk(KERN_ERR "cirrusfb: could not register " @@ -2305,7 +2210,6 @@ static int cirrusfb_register(struct fb_info *info) err_dealloc_cmap: fb_dealloc_cmap(&info->cmap); -err_unmap_cirrusfb: cinfo->unmap(info); framebuffer_release(info); return err; @@ -2351,7 +2255,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, } cinfo = info->par; - cinfo->pdev = pdev; cinfo->btype = btype = (enum cirrus_board) ent->driver_data; DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n", @@ -2487,7 +2390,6 @@ static int cirrusfb_zorro_register(struct zorro_dev *z, assert(z); assert(btype != BT_NONE); - cinfo->zdev = z; board_addr = zorro_resource_start(z); board_size = zorro_resource_len(z); info->screen_size = size; @@ -2619,17 +2521,17 @@ static int __init cirrusfb_setup(char *options) { return 0; while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) continue; + if (!*this_opt) + continue; DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); - for (i = 0; i < NUM_TOTAL_MODES; i++) { - sprintf(s, "mode:%s", cirrusfb_predefined[i].name); - if (strcmp(this_opt, s) == 0) - cirrusfb_def_mode = i; - } if (!strcmp(this_opt, "noaccel")) noaccel = 1; + else if (!strncmp(this_opt, "mode:", 5)) + mode_option = this_opt + 5; + else + mode_option = this_opt; } return 0; } @@ -2655,6 +2557,9 @@ static void __exit cirrusfb_exit(void) module_init(cirrusfb_init); +module_param(mode_option, charp, 0); +MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'"); + #ifdef MODULE module_exit(cirrusfb_exit); #endif