📄 i810_main.c
字号:
} if (agp_bind_memory(par->i810_gtt.i810_fb_memory, par->fb.offset)) { printk("i810fb_alloc_fbmem: can't bind framebuffer memory\n"); agp_backend_release(bridge); return -EBUSY; } if (!(par->i810_gtt.i810_cursor_memory = agp_allocate_memory(bridge, par->cursor_heap.size >> 12, AGP_PHYSICAL_MEMORY))) { printk("i810fb_alloc_cursormem: can't allocate" "cursor memory\n"); agp_backend_release(bridge); return -ENOMEM; } if (agp_bind_memory(par->i810_gtt.i810_cursor_memory, par->cursor_heap.offset)) { printk("i810fb_alloc_cursormem: cannot bind cursor memory\n"); agp_backend_release(bridge); return -EBUSY; } par->cursor_heap.physical = par->i810_gtt.i810_cursor_memory->physical; i810_fix_pointers(par); agp_backend_release(bridge); return 0;}/*************************************************************** * Initialization * ***************************************************************//** * i810_init_monspecs * @info: pointer to device specific info structure * * DESCRIPTION: * Sets the the user monitor's horizontal and vertical * frequency limits */static void __devinit i810_init_monspecs(struct fb_info *info){ if (!hsync1) hsync1 = HFMIN; if (!hsync2) hsync2 = HFMAX; if (!info->monspecs.hfmax) info->monspecs.hfmax = hsync2; if (!info->monspecs.hfmin) info->monspecs.hfmin = hsync1; if (hsync2 < hsync1) info->monspecs.hfmin = hsync2; if (!vsync1) vsync1 = VFMIN; if (!vsync2) vsync2 = VFMAX; if (IS_DVT && vsync1 < 60) vsync1 = 60; if (!info->monspecs.vfmax) info->monspecs.vfmax = vsync2; if (!info->monspecs.vfmin) info->monspecs.vfmin = vsync1; if (vsync2 < vsync1) info->monspecs.vfmin = vsync2;}/** * i810_init_defaults - initializes default values to use * @par: pointer to i810fb_par structure * @info: pointer to current fb_info structure */static void __devinit i810_init_defaults(struct i810fb_par *par, struct fb_info *info){ if (voffset) v_offset_default = voffset; else if (par->aperture.size > 32 * 1024 * 1024) v_offset_default = 16; else v_offset_default = 8; if (!vram) vram = 1; if (accel) par->dev_flags |= HAS_ACCELERATION; if (sync) par->dev_flags |= ALWAYS_SYNC; if (bpp < 8) bpp = 8; par->i810fb_ops = i810fb_ops; if (xres) info->var.xres = xres; else info->var.xres = 640; if (yres) info->var.yres = yres; else info->var.yres = 480; if (!vyres) vyres = (vram << 20)/(info->var.xres*bpp >> 3); info->var.yres_virtual = vyres; info->var.bits_per_pixel = bpp; if (dcolor) info->var.nonstd = 1; if (par->dev_flags & HAS_ACCELERATION) info->var.accel_flags = 1; i810_init_monspecs(info);} /** * i810_init_device - initialize device * @par: pointer to i810fb_par structure */static void __devinit i810_init_device(struct i810fb_par *par){ u8 reg; u8 __iomem *mmio = par->mmio_start_virtual; if (mtrr) set_mtrr(par); i810_init_cursor(par); /* mvo: enable external vga-connector (for laptops) */ if (extvga) { i810_writel(HVSYNC, mmio, 0); i810_writel(PWR_CLKC, mmio, 3); } pci_read_config_byte(par->dev, 0x50, ®); reg &= FREQ_MASK; par->mem_freq = (reg) ? 133 : 100;}static int __devinit i810_allocate_pci_resource(struct i810fb_par *par, const struct pci_device_id *entry){ int err; if ((err = pci_enable_device(par->dev))) { printk("i810fb_init: cannot enable device\n"); return err; } par->res_flags |= PCI_DEVICE_ENABLED; if (pci_resource_len(par->dev, 0) > 512 * 1024) { par->aperture.physical = pci_resource_start(par->dev, 0); par->aperture.size = pci_resource_len(par->dev, 0); par->mmio_start_phys = pci_resource_start(par->dev, 1); } else { par->aperture.physical = pci_resource_start(par->dev, 1); par->aperture.size = pci_resource_len(par->dev, 1); par->mmio_start_phys = pci_resource_start(par->dev, 0); } if (!par->aperture.size) { printk("i810fb_init: device is disabled\n"); return -ENOMEM; } if (!request_mem_region(par->aperture.physical, par->aperture.size, i810_pci_list[entry->driver_data])) { printk("i810fb_init: cannot request framebuffer region\n"); return -ENODEV; } par->res_flags |= FRAMEBUFFER_REQ; par->aperture.virtual = ioremap_nocache(par->aperture.physical, par->aperture.size); if (!par->aperture.virtual) { printk("i810fb_init: cannot remap framebuffer region\n"); return -ENODEV; } if (!request_mem_region(par->mmio_start_phys, MMIO_SIZE, i810_pci_list[entry->driver_data])) { printk("i810fb_init: cannot request mmio region\n"); return -ENODEV; } par->res_flags |= MMIO_REQ; par->mmio_start_virtual = ioremap_nocache(par->mmio_start_phys, MMIO_SIZE); if (!par->mmio_start_virtual) { printk("i810fb_init: cannot remap mmio region\n"); return -ENODEV; } return 0;}static void __devinit i810fb_find_init_mode(struct fb_info *info){ struct fb_videomode mode; struct fb_var_screeninfo var; struct fb_monspecs *specs = &info->monspecs; int found = 0;#ifdef CONFIG_FB_I810_I2C int i; int err; struct i810fb_par *par = info->par;#endif INIT_LIST_HEAD(&info->modelist); memset(&mode, 0, sizeof(struct fb_videomode)); var = info->var;#ifdef CONFIG_FB_I810_I2C i810_create_i2c_busses(par); for (i = 0; i < 4; i++) { err = i810_probe_i2c_connector(info, &par->edid, i+1); if (!err) break; } if (!err) printk("i810fb_init_pci: DDC probe successful\n"); fb_edid_to_monspecs(par->edid, specs); if (specs->modedb == NULL) printk("i810fb_init_pci: Unable to get Mode Database\n"); fb_videomode_to_modelist(specs->modedb, specs->modedb_len, &info->modelist); if (specs->modedb != NULL) { struct fb_videomode *m; if (xres && yres) { if ((m = fb_find_best_mode(&var, &info->modelist))) { mode = *m; found = 1; } } if (!found) { m = fb_find_best_display(&info->monspecs, &info->modelist); mode = *m; found = 1; } fb_videomode_to_var(&var, &mode); }#endif if (mode_option) fb_find_mode(&var, info, mode_option, specs->modedb, specs->modedb_len, (found) ? &mode : NULL, info->var.bits_per_pixel); info->var = var; fb_destroy_modedb(specs->modedb); specs->modedb = NULL;}#ifndef MODULEstatic int __devinit i810fb_setup(char *options){ char *this_opt, *suffix = NULL; if (!options || !*options) return 0; while ((this_opt = strsep(&options, ",")) != NULL) { if (!strncmp(this_opt, "mtrr", 4)) mtrr = 1; else if (!strncmp(this_opt, "accel", 5)) accel = 1; else if (!strncmp(this_opt, "extvga", 6)) extvga = 1; else if (!strncmp(this_opt, "sync", 4)) sync = 1; else if (!strncmp(this_opt, "vram:", 5)) vram = (simple_strtoul(this_opt+5, NULL, 0)); else if (!strncmp(this_opt, "voffset:", 8)) voffset = (simple_strtoul(this_opt+8, NULL, 0)); else if (!strncmp(this_opt, "xres:", 5)) xres = simple_strtoul(this_opt+5, NULL, 0); else if (!strncmp(this_opt, "yres:", 5)) yres = simple_strtoul(this_opt+5, NULL, 0); else if (!strncmp(this_opt, "vyres:", 6)) vyres = simple_strtoul(this_opt+6, NULL, 0); else if (!strncmp(this_opt, "bpp:", 4)) bpp = simple_strtoul(this_opt+4, NULL, 0); else if (!strncmp(this_opt, "hsync1:", 7)) { hsync1 = simple_strtoul(this_opt+7, &suffix, 0); if (strncmp(suffix, "H", 1)) hsync1 *= 1000; } else if (!strncmp(this_opt, "hsync2:", 7)) { hsync2 = simple_strtoul(this_opt+7, &suffix, 0); if (strncmp(suffix, "H", 1)) hsync2 *= 1000; } else if (!strncmp(this_opt, "vsync1:", 7)) vsync1 = simple_strtoul(this_opt+7, NULL, 0); else if (!strncmp(this_opt, "vsync2:", 7)) vsync2 = simple_strtoul(this_opt+7, NULL, 0); else if (!strncmp(this_opt, "dcolor", 6)) dcolor = 1; else mode_option = this_opt; } return 0;}#endifstatic int __devinit i810fb_init_pci (struct pci_dev *dev, const struct pci_device_id *entry){ struct fb_info *info; struct i810fb_par *par = NULL; struct fb_videomode mode; int i, err = -1, vfreq, hfreq, pixclock; i = 0; info = framebuffer_alloc(sizeof(struct i810fb_par), &dev->dev); if (!info) return -ENOMEM; par = info->par; par->dev = dev; if (!(info->pixmap.addr = kmalloc(8*1024, GFP_KERNEL))) { i810fb_release_resource(info, par); return -ENOMEM; } memset(info->pixmap.addr, 0, 8*1024); info->pixmap.size = 8*1024; info->pixmap.buf_align = 8; info->pixmap.access_align = 32; info->pixmap.flags = FB_PIXMAP_SYSTEM; if ((err = i810_allocate_pci_resource(par, entry))) { i810fb_release_resource(info, par); return err; } i810_init_defaults(par, info); if ((err = i810_alloc_agp_mem(info))) { i810fb_release_resource(info, par); return err; } i810_init_device(par); info->screen_base = par->fb.virtual; info->fbops = &par->i810fb_ops; info->pseudo_palette = par->pseudo_palette; fb_alloc_cmap(&info->cmap, 256, 0); i810fb_find_init_mode(info); if ((err = info->fbops->fb_check_var(&info->var, info))) { i810fb_release_resource(info, par); return err; } fb_var_to_videomode(&mode, &info->var); fb_add_videomode(&mode, &info->modelist); encode_fix(&info->fix, info); i810fb_init_ringbuffer(info); err = register_framebuffer(info); if (err < 0) { i810fb_release_resource(info, par); printk("i810fb_init: cannot register framebuffer device\n"); return err; } pci_set_drvdata(dev, info); pixclock = 1000000000/(info->var.pixclock); pixclock *= 1000; hfreq = pixclock/(info->var.xres + info->var.left_margin + info->var.hsync_len + info->var.right_margin); vfreq = hfreq/(info->var.yres + info->var.upper_margin + info->var.vsync_len + info->var.lower_margin); printk("I810FB: fb%d : %s v%d.%d.%d%s\n" "I810FB: Video RAM : %dK\n" "I810FB: Monitor : H: %d-%d KHz V: %d-%d Hz\n" "I810FB: Mode : %dx%d-%dbpp@%dHz\n", info->node, i810_pci_list[entry->driver_data], VERSION_MAJOR, VERSION_MINOR, VERSION_TEENIE, BRANCH_VERSION, (int) par->fb.size>>10, info->monspecs.hfmin/1000, info->monspecs.hfmax/1000, info->monspecs.vfmin, info->monspecs.vfmax, info->var.xres, info->var.yres, info->var.bits_per_pixel, vfreq); return 0;}/*************************************************************** * De-initialization * ***************************************************************/static void i810fb_release_resource(struct fb_info *info, struct i810fb_par *par){ struct gtt_data *gtt = &par->i810_gtt; unset_mtrr(par); i810_delete_i2c_busses(par); if (par->i810_gtt.i810_cursor_memory) agp_free_memory(gtt->i810_cursor_memory); if (par->i810_gtt.i810_fb_memory) agp_free_memory(gtt->i810_fb_memory); if (par->mmio_start_virtual) iounmap(par->mmio_start_virtual); if (par->aperture.virtual) iounmap(par->aperture.virtual); kfree(par->edid); if (par->res_flags & FRAMEBUFFER_REQ) release_mem_region(par->aperture.physical, par->aperture.size); if (par->res_flags & MMIO_REQ) release_mem_region(par->mmio_start_phys, MMIO_SIZE); if (par->res_flags & PCI_DEVICE_ENABLED) pci_disable_device(par->dev); framebuffer_release(info);}static void __exit i810fb_remove_pci(struct pci_dev *dev){ struct fb_info *info = pci_get_drvdata(dev); struct i810fb_par *par = (struct i810fb_par *) info->par; unregister_framebuffer(info); i810fb_release_resource(info, par); pci_set_drvdata(dev, NULL); printk("cleanup_module: unloaded i810 framebuffer device\n");} #ifndef MODULEstatic int __devinit i810fb_init(void){ char *option = NULL; if (fb_get_options("i810fb", &option)) return -ENODEV; i810fb_setup(option); return pci_register_driver(&i810fb_driver);}#endif /********************************************************************* * Modularization * *********************************************************************/#ifdef MODULEstatic int __devinit i810fb_init(void){ hsync1 *= 1000; hsync2 *= 1000; return pci_register_driver(&i810fb_driver);}module_param(vram, int, 0);MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB" " (default=4)");module_param(voffset, int, 0);MODULE_PARM_DESC(voffset, "at what offset to place start of framebuffer " "memory (0 to maximum aperture size), in MiB (default = 48)");module_param(bpp, int, 0);MODULE_PARM_DESC(bpp, "Color depth for display in bits per pixel" " (default = 8)");module_param(xres, int, 0);MODULE_PARM_DESC(xres, "Horizontal resolution in pixels (default = 640)");module_param(yres, int, 0);MODULE_PARM_DESC(yres, "Vertical resolution in scanlines (default = 480)");module_param(vyres,int, 0);MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines" " (default = 480)");module_param(hsync1, int, 0);MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz" " (default = 29)");module_param(hsync2, int, 0);MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz" " (default = 30)");module_param(vsync1, int, 0);MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz" " (default = 50)");module_param(vsync2, int, 0);MODULE_PARM_DESC(vsync2, "Maximum vertical frequency of monitor in Hz" " (default = 60)");module_param(accel, bool, 0);MODULE_PARM_DESC(accel, "Use Acceleration (BLIT) engine (default = 0)");module_param(mtrr, bool, 0);MODULE_PARM_DESC(mtrr, "Use MTRR (default = 0)");module_param(extvga, bool, 0);MODULE_PARM_DESC(extvga, "Enable external VGA connector (default = 0)");module_param(sync, bool, 0);MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing" " (default = 0)");module_param(dcolor, bool, 0);MODULE_PARM_DESC(dcolor, "use DirectColor visuals" " (default = 0 = TrueColor)");module_param(mode_option, charp, 0);MODULE_PARM_DESC(mode_option, "Specify initial video mode");MODULE_AUTHOR("Tony A. Daplas");MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and" " compatible cards");MODULE_LICENSE("GPL"); static void __exit i810fb_exit(void){ pci_unregister_driver(&i810fb_driver);}module_exit(i810fb_exit);#endif /* MODULE */module_init(i810fb_init);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -