📄 stifb.c
字号:
static intstifb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ memcpy (var, &((struct stifb_info *)info)->var, sizeof (*var)); return 0;}static intstifb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct display *disp; if (con >= 0) disp = &fb_display[con]; else disp = info->disp; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { if (disp->var.xres != var->xres || disp->var.yres != var->yres || disp->var.xres_virtual != var->xres_virtual || disp->var.yres_virtual != var->yres_virtual || disp->var.bits_per_pixel != var->bits_per_pixel || disp->var.accel_flags != var->accel_flags) return -EINVAL; } return 0;}static intstifb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ struct stifb_info *fb = (struct stifb_info *)info; if (con == fb->currcon) /* current console ? */ return fb_get_cmap(cmap, kspc, stifb_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(fb_display[con].var.bits_per_pixel > 8 ? 16 : 256), cmap, kspc ? 0: 2); return 0;}static intstifb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ struct stifb_info *fb = (struct stifb_info *)info; struct display *disp; int err; if (con >= 0) disp = &fb_display[con]; else disp = info->disp; if (!disp->cmap.len) { /* no colormap allocated ? */ if ((err = fb_alloc_cmap(&disp->cmap, disp->var.bits_per_pixel > 8 ? 16 : 256, 0))) return err; } if (con == fb->currcon || con == -1) { err = fb_set_cmap(cmap, kspc, stifb_setcolreg, info); if (!err) stifb_loadcmap ((struct stifb_info *)info); return err; } else fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1); return 0;} static voidstifb_blank(int blank_mode, struct fb_info *info){ struct stifb_info *fb = (struct stifb_info *) info; int enable = (blank_mode == 0) ? ENABLE : DISABLE; switch (fb->id) { case S9000_ID_A1439A: CRX24_ENABLE_DISABLE_DISPLAY(fb, enable); break; case CRT_ID_VISUALIZE_EG: case S9000_ID_ARTIST: ARTIST_ENABLE_DISABLE_DISPLAY(fb, enable); break; case S9000_ID_HCRX: HYPER_ENABLE_DISABLE_DISPLAY(fb, enable); break; case S9000_ID_A1659A:; /* fall through */ case S9000_ID_TIMBER:; case CRX24_OVERLAY_PLANES:; default: ENABLE_DISABLE_DISPLAY(fb, enable); break; } SETUP_FB(fb);}static voidstifb_set_disp(struct stifb_info *fb){ int id = fb->id; SETUP_FB(fb); /* HCRX specific initialization */ SETUP_HCRX(fb); /* if (id == S9000_ID_HCRX) hyperInitSprite(fb); else ngleInitSprite(fb); */ /* Initialize the image planes. */ switch (id) { case S9000_ID_HCRX: hyperResetPlanes(fb, ENABLE); break; case S9000_ID_A1439A: rattlerSetupPlanes(fb); break; case S9000_ID_A1659A: case S9000_ID_ARTIST: case CRT_ID_VISUALIZE_EG: elkSetupPlanes(fb); break; } /* Clear attribute planes on non HCRX devices. */ switch (id) { case S9000_ID_A1659A: case S9000_ID_A1439A: if (fb->var.bits_per_pixel == 32) ngleSetupAttrPlanes(fb, BUFF1_CMAP3); else { ngleSetupAttrPlanes(fb, BUFF1_CMAP0); } if (id == S9000_ID_A1439A) ngleClearOverlayPlanes(fb, 0xff, 0); break; case S9000_ID_ARTIST: case CRT_ID_VISUALIZE_EG: if (fb->var.bits_per_pixel == 32) ngleSetupAttrPlanes(fb, BUFF1_CMAP3); else { ngleSetupAttrPlanes(fb, ARTIST_CMAP0); } break; } stifb_blank(0, (struct fb_info *)fb); /* 0=enable screen */ SETUP_FB(fb);}static intstifb_switch(int con, struct fb_info *info){ struct stifb_info *fb = (struct stifb_info *)info; /* Do we have to save the colormap ? */ if (fb->currcon != -1 && fb_display[fb->currcon].cmap.len) fb_get_cmap(&fb_display[fb->currcon].cmap, 1, stifb_getcolreg, info); fb->currcon = con; /* Install new colormap */ if (fb_display[con].cmap.len) fb_set_cmap(&fb_display[con].cmap, 1, stifb_setcolreg, info); else fb_set_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel > 8 ? 16 : 256), 1, stifb_setcolreg, info); stifb_loadcmap ((struct stifb_info *)info); return 0;}static intstifb_update_var(int con, struct fb_info *info){ return 0;}/* ------------ Interfaces to hardware functions ------------ */static struct fb_ops stifb_ops = { owner: THIS_MODULE, fb_get_fix: stifb_get_fix, fb_get_var: stifb_get_var, fb_set_var: stifb_set_var, fb_get_cmap: stifb_get_cmap, fb_set_cmap: stifb_set_cmap,// fb_pan_display: fbgen_pan_display,// fb_ioctl: xxxfb_ioctl, /* optional */ }; /* * Initialization */int __initstifb_init_fb(struct sti_struct *sti, int force_bpp){ struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; struct display *disp; struct stifb_info *fb; unsigned long sti_rom_address; char *dev_name; int bpp, xres, yres; fb = kmalloc(sizeof(struct stifb_info), GFP_ATOMIC); if (!fb) { printk(KERN_ERR "stifb: Could not allocate stifb structure\n"); return -ENODEV; } /* set struct to a known state */ memset(fb, 0, sizeof(struct stifb_info)); fix = &fb->fix; var = &fb->var; disp = &fb->disp; fb->currcon = -1; fb->cmap_reload = 1; fb->sti = sti; /* store upper 32bits of the graphics id */ fb->id = fb->sti->graphics_id[0]; fb->real_id = fb->id; /* save the real id */ /* only supported cards are allowed */ switch (fb->id) { case S9000_ID_ARTIST: case S9000_ID_HCRX: case S9000_ID_TIMBER: case S9000_ID_A1659A: case S9000_ID_A1439A: case CRT_ID_VISUALIZE_EG: break; default: printk(KERN_WARNING "stifb: Unsupported gfx card id 0x%08x\n", fb->id); goto out_err1; } /* default to 8 bpp on most graphic chips */ bpp = 8; xres = sti_onscreen_x(fb->sti); yres = sti_onscreen_y(fb->sti); ngleGetDeviceRomData(fb); /* get (virtual) io region base addr */ fix->mmio_start = REGION_BASE(fb,2); fix->mmio_len = 0x400000; /* Reject any device not in the NGLE family */ switch (fb->id) { case S9000_ID_A1659A: /* CRX/A1659A */ break; case S9000_ID_ELM: /* GRX, grayscale but else same as A1659A */ var->grayscale = 1; fb->id = S9000_ID_A1659A; break; case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */ dev_name = fb->sti->outptr.dev_name; if (strstr(dev_name, "GRAYSCALE") || strstr(dev_name, "Grayscale") || strstr(dev_name, "grayscale")) var->grayscale = 1; break; case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */ /* FIXME: TomCat supports two heads: * fb.iobase = REGION_BASE(fb_info,3); * fb.screen_base = (void*) REGION_BASE(fb_info,2); * for now we only support the left one ! */ xres = fb->ngle_rom.x_size_visible; yres = fb->ngle_rom.y_size_visible; fb->id = S9000_ID_A1659A; break; case S9000_ID_A1439A: /* CRX24/A1439A */ if (force_bpp == 8 || force_bpp == 32) bpp = force_bpp; else bpp = 32; break; case S9000_ID_HCRX: /* Hyperdrive/HCRX */ memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom)); if ((fb->sti->regions_phys[0] & 0xfc000000) == (fb->sti->regions_phys[2] & 0xfc000000)) sti_rom_address = fb->sti->regions_phys[0]; else sti_rom_address = fb->sti->regions_phys[1];#ifdef __LP64__ sti_rom_address |= 0xffffffff00000000;#endif fb->deviceSpecificConfig = __raw_readl(sti_rom_address); if (IS_24_DEVICE(fb)) { if (force_bpp == 8 || force_bpp == 32) bpp = force_bpp; else bpp = 32; } else bpp = 8; READ_WORD(fb, REG_15); SETUP_HW(fb); break; case CRT_ID_VISUALIZE_EG: case S9000_ID_ARTIST: /* Artist */ break; default: #ifdef FALLBACK_TO_1BPP printk(KERN_WARNING "stifb: Unsupported graphics card (id=0x%08x) " "- now trying 1bpp mode instead\n", fb->id); bpp = 1; /* default to 1 bpp */ break;#else printk(KERN_WARNING "stifb: Unsupported graphics card (id=0x%08x) " "- skipping.\n", fb->id); goto out_err1;#endif } /* get framebuffer pysical and virtual base addr & len (64bit ready) */ fix->smem_start = fb->sti->regions_phys[1] | 0xffffffff00000000; fix->smem_len = fb->sti->regions[1].region_desc.length * 4096; fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8; if (!fix->line_length) fix->line_length = 2048; /* default */ fix->accel = FB_ACCEL_NONE; switch (bpp) { case 1: fix->type = FB_TYPE_PLANES; /* well, sort of */ fix->visual = FB_VISUAL_MONO10; disp->dispsw = &fbcon_sti; break;#ifdef FBCON_HAS_CFB8 case 8: fix->type = FB_TYPE_PACKED_PIXELS; fix->visual = FB_VISUAL_PSEUDOCOLOR; disp->dispsw = &fbcon_cfb8; var->red.length = var->green.length = var->blue.length = 8; break;#endif#ifdef FBCON_HAS_CFB32 case 32: fix->type = FB_TYPE_PACKED_PIXELS; fix->visual = FB_VISUAL_TRUECOLOR; disp->dispsw = &fbcon_cfb32; disp->dispsw_data = fb->fbcon_cmap.cfb32; var->red.length = var->green.length = var->blue.length = var->transp.length = 8; var->blue.offset = 0; var->green.offset = 8; var->red.offset = 16; var->transp.offset = 24; break;#endif default: disp->dispsw = &fbcon_dummy; break; } var->xres = var->xres_virtual = xres; var->yres = var->yres_virtual = yres; var->bits_per_pixel = bpp; disp->var = *var; disp->visual = fix->visual; disp->type = fix->type; disp->type_aux = fix->type_aux; disp->line_length = fix->line_length; disp->var.activate = FB_ACTIVATE_NOW; disp->screen_base = (void*) REGION_BASE(fb,1); disp->can_soft_blank = 1; disp->scrollmode = SCROLL_YREDRAW; strcpy(fb->info.modename, "stifb"); fb->info.node = -1; fb->info.flags = FBINFO_FLAG_DEFAULT; fb->info.fbops = &stifb_ops; fb->info.disp = disp; fb->info.changevar = NULL; fb->info.switch_con = &stifb_switch; fb->info.updatevar = &stifb_update_var; fb->info.blank = &stifb_blank; fb->info.flags = FBINFO_FLAG_DEFAULT; stifb_set_var(&disp->var, 1, &fb->info); stifb_set_disp(fb); if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb")) { printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n", fix->smem_start, fix->smem_start+fix->smem_len); goto out_err1; } if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) { printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n", fix->mmio_start, fix->mmio_start+fix->mmio_len); goto out_err2; } if (register_framebuffer(&fb->info) < 0) goto out_err3; printk(KERN_INFO "fb%d: %s %dx%d-%d frame buffer device, id: %04x, mmio: 0x%04lx\n", GET_FB_IDX(fb->info.node), fb->info.modename, disp->var.xres, disp->var.yres, disp->var.bits_per_pixel, fb->id, fix->mmio_start); return 0;out_err3: release_mem_region(fix->mmio_start, fix->mmio_len);out_err2: release_mem_region(fix->smem_start, fix->smem_len);out_err1: kfree(fb); return -ENXIO;}int __initstifb_init(void){ struct sti_struct *sti; int i; if (sti_init_roms() == NULL) return -ENXIO; /* no STI cards available */ for (i = 0; i < MAX_STI_ROMS; i++) { sti = sti_get_rom(i); if (sti) stifb_init_fb (sti, stifb_force_bpp[i]); else break; } return 0;}/* * Cleanup */void __exitstifb_cleanup(struct fb_info *info){ // unregister_framebuffer(info); }int __initstifb_setup(char *options){ int i; if (!options || !*options) return 0; if (strncmp(options, "bpp", 3) == 0) { options += 3; for (i = 0; i < MAX_STI_ROMS; i++) { if (*options++ == ':') stifb_force_bpp[i] = simple_strtoul(options, &options, 10); else break; } } return 0;}__setup("stifb=", stifb_setup);#ifdef MODULEmodule_init(stifb_init);#endifmodule_exit(stifb_cleanup);MODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>");MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines");MODULE_LICENSE("GPL");MODULE_PARM(bpp, "i");MODULE_PARM_DESC(mem, "Bits per pixel (default: 8)");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -