📄 w100fb.c
字号:
w100_setup_memory(par); w100_init_clocks(par); w100fb_clear_screen(par); w100_vsync(); w100_update_disable(); w100_init_lcd(par); w100_set_dispregs(par); w100_update_enable(); w100_init_graphic_engine(par); calc_hsync(par); if (!par->blanked && tg && tg->change) tg->change(par);}/* Select the smallest mode that allows the desired resolution to be * displayed. If desired, the x and y parameters can be rounded up to * match the selected mode. */static struct w100_mode *w100fb_get_mode(struct w100fb_par *par, unsigned int *x, unsigned int *y, int saveval){ struct w100_mode *mode = NULL; struct w100_mode *modelist = par->mach->modelist; unsigned int best_x = 0xffffffff, best_y = 0xffffffff; unsigned int i; for (i = 0 ; i < par->mach->num_modes ; i++) { if (modelist[i].xres >= *x && modelist[i].yres >= *y && modelist[i].xres < best_x && modelist[i].yres < best_y) { best_x = modelist[i].xres; best_y = modelist[i].yres; mode = &modelist[i]; } else if(modelist[i].xres >= *y && modelist[i].yres >= *x && modelist[i].xres < best_y && modelist[i].yres < best_x) { best_x = modelist[i].yres; best_y = modelist[i].xres; mode = &modelist[i]; } } if (mode && saveval) { *x = best_x; *y = best_y; } return mode;}/* * w100fb_check_var(): * Get the video params out of 'var'. If a value doesn't fit, round it up, * if it's too big, return -EINVAL. */static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){ struct w100fb_par *par=info->par; if(!w100fb_get_mode(par, &var->xres, &var->yres, 1)) return -EINVAL; if (par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (par->mach->mem->size+1))) return -EINVAL; if (!par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1))) return -EINVAL; var->xres_virtual = max(var->xres_virtual, var->xres); var->yres_virtual = max(var->yres_virtual, var->yres); if (var->bits_per_pixel > BITS_PER_PIXEL) return -EINVAL; else var->bits_per_pixel = BITS_PER_PIXEL; var->red.offset = 11; var->red.length = 5; var->green.offset = 5; var->green.length = 6; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = var->transp.length = 0; var->nonstd = 0; var->height = -1; var->width = -1; var->vmode = FB_VMODE_NONINTERLACED; var->sync = 0; var->pixclock = 0x04; /* 171521; */ return 0;}/* * w100fb_set_par(): * Set the user defined part of the display for the specified console * by looking at the values in info.var */static int w100fb_set_par(struct fb_info *info){ struct w100fb_par *par=info->par; if (par->xres != info->var.xres || par->yres != info->var.yres) { par->xres = info->var.xres; par->yres = info->var.yres; par->mode = w100fb_get_mode(par, &par->xres, &par->yres, 0); info->fix.visual = FB_VISUAL_TRUECOLOR; info->fix.ypanstep = 0; info->fix.ywrapstep = 0; info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { par->extmem_active = 1; info->fix.smem_len = par->mach->mem->size+1; } else { par->extmem_active = 0; info->fix.smem_len = MEM_INT_SIZE+1; } w100fb_activate_var(par); } return 0;}/* * Frame buffer operations */static struct fb_ops w100fb_ops = { .owner = THIS_MODULE, .fb_check_var = w100fb_check_var, .fb_set_par = w100fb_set_par, .fb_setcolreg = w100fb_setcolreg, .fb_blank = w100fb_blank, .fb_fillrect = w100fb_fillrect, .fb_copyarea = w100fb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = w100fb_sync,};#ifdef CONFIG_PMstatic void w100fb_save_vidmem(struct w100fb_par *par){ int memsize; if (par->extmem_active) { memsize=par->mach->mem->size; par->saved_extmem = vmalloc(memsize); if (par->saved_extmem) memcpy_fromio(par->saved_extmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize); } memsize=MEM_INT_SIZE; par->saved_intmem = vmalloc(memsize); if (par->saved_intmem && par->extmem_active) memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), memsize); else if (par->saved_intmem) memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize);}static void w100fb_restore_vidmem(struct w100fb_par *par){ int memsize; if (par->extmem_active && par->saved_extmem) { memsize=par->mach->mem->size; memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize); vfree(par->saved_extmem); } if (par->saved_intmem) { memsize=MEM_INT_SIZE; if (par->extmem_active) memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), par->saved_intmem, memsize); else memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize); vfree(par->saved_intmem); }}static int w100fb_suspend(struct platform_device *dev, pm_message_t state){ struct fb_info *info = platform_get_drvdata(dev); struct w100fb_par *par=info->par; struct w100_tg_info *tg = par->mach->tg; w100fb_save_vidmem(par); if(tg && tg->suspend) tg->suspend(par); w100_suspend(W100_SUSPEND_ALL); par->blanked = 1; return 0;}static int w100fb_resume(struct platform_device *dev){ struct fb_info *info = platform_get_drvdata(dev); struct w100fb_par *par=info->par; struct w100_tg_info *tg = par->mach->tg; w100_hw_init(par); w100fb_activate_var(par); w100fb_restore_vidmem(par); if(tg && tg->resume) tg->resume(par); par->blanked = 0; return 0;}#else#define w100fb_suspend NULL#define w100fb_resume NULL#endifint __init w100fb_probe(struct platform_device *pdev){ int err = -EIO; struct w100fb_mach_info *inf; struct fb_info *info = NULL; struct w100fb_par *par; struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); unsigned int chip_id; if (!mem) return -EINVAL; /* Remap the chip base address */ remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN); if (remapped_base == NULL) goto out; /* Map the register space */ remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN); if (remapped_regs == NULL) goto out; /* Identify the chip */ printk("Found "); chip_id = readl(remapped_regs + mmCHIP_ID); switch(chip_id) { case CHIP_ID_W100: printk("w100"); break; case CHIP_ID_W3200: printk("w3200"); break; case CHIP_ID_W3220: printk("w3220"); break; default: printk("Unknown imageon chip ID\n"); err = -ENODEV; goto out; } printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE); /* Remap the framebuffer */ remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE); if (remapped_fbuf == NULL) goto out; info=framebuffer_alloc(sizeof(struct w100fb_par), &pdev->dev); if (!info) { err = -ENOMEM; goto out; } par = info->par; platform_set_drvdata(pdev, info); inf = pdev->dev.platform_data; par->chip_id = chip_id; par->mach = inf; par->fastpll_mode = 0; par->blanked = 0; par->pll_table=w100_get_xtal_table(inf->xtal_freq); if (!par->pll_table) { printk(KERN_ERR "No matching Xtal definition found\n"); err = -EINVAL; goto out; } info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL); if (!info->pseudo_palette) { err = -ENOMEM; goto out; } info->fbops = &w100fb_ops; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; info->node = -1; info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); info->screen_size = REMAPPED_FB_LEN; strcpy(info->fix.id, "w100fb"); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.type_aux = 0; info->fix.accel = FB_ACCEL_NONE; info->fix.smem_start = mem->start+W100_FB_BASE; info->fix.mmio_start = mem->start+W100_REG_BASE; info->fix.mmio_len = W100_REG_LEN; if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { err = -ENOMEM; goto out; } par->mode = &inf->modelist[0]; if(inf->init_mode & INIT_MODE_ROTATED) { info->var.xres = par->mode->yres; info->var.yres = par->mode->xres; } else { info->var.xres = par->mode->xres; info->var.yres = par->mode->yres; } if(inf->init_mode &= INIT_MODE_FLIPPED) par->flip = 1; else par->flip = 0; info->var.xres_virtual = info->var.xres; info->var.yres_virtual = info->var.yres; info->var.pixclock = 0x04; /* 171521; */ info->var.sync = 0; info->var.grayscale = 0; info->var.xoffset = info->var.yoffset = 0; info->var.accel_flags = 0; info->var.activate = FB_ACTIVATE_NOW; w100_hw_init(par); if (w100fb_check_var(&info->var, info) < 0) { err = -EINVAL; goto out; } w100fb_set_par(info); if (register_framebuffer(info) < 0) { err = -EINVAL; goto out; } err = device_create_file(&pdev->dev, &dev_attr_fastpllclk); err |= device_create_file(&pdev->dev, &dev_attr_reg_read); err |= device_create_file(&pdev->dev, &dev_attr_reg_write); err |= device_create_file(&pdev->dev, &dev_attr_flip); if (err != 0) printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", info->node, err); printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); return 0;out: if (info) { fb_dealloc_cmap(&info->cmap); kfree(info->pseudo_palette); } if (remapped_fbuf != NULL) iounmap(remapped_fbuf); if (remapped_regs != NULL) iounmap(remapped_regs); if (remapped_base != NULL) iounmap(remapped_base); if (info) framebuffer_release(info); return err;}static int w100fb_remove(struct platform_device *pdev){ struct fb_info *info = platform_get_drvdata(pdev); struct w100fb_par *par=info->par; device_remove_file(&pdev->dev, &dev_attr_fastpllclk); device_remove_file(&pdev->dev, &dev_attr_reg_read); device_remove_file(&pdev->dev, &dev_attr_reg_write); device_remove_file(&pdev->dev, &dev_attr_flip); unregister_framebuffer(info); vfree(par->saved_intmem); vfree(par->saved_extmem); kfree(info->pseudo_palette); fb_dealloc_cmap(&info->cmap); iounmap(remapped_base); iounmap(remapped_regs); iounmap(remapped_fbuf); framebuffer_release(info); return 0;}/* ------------------- chipset specific functions -------------------------- */static void w100_soft_reset(void){ u16 val = readw((u16 *) remapped_base + cfgSTATUS); writew(val | 0x08, (u16 *) remapped_base + cfgSTATUS); udelay(100);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -