/*! * Initializes the framebuffer information pointer. After allocating * sufficient memory for the framebuffer structure, the fields are * filled with custom information passed in from the configurable * structures. This includes information such as bits per pixel, * color maps, screen width/height and RGBA offsets. * * @return Framebuffer structure initialized with our information */ static struct fb_info *mxcfb_init_fbinfo(struct device *dev, struct fb_ops *ops) { struct fb_info *fbi; struct mxcfb_info *mxcfbi; /* * Allocate sufficient memory for the fb structure */ fbi = framebuffer_alloc(sizeof(struct mxcfb_info), dev); if (!fbi) return NULL; mxcfbi = (struct mxcfb_info *)fbi->par; /* * Fill in fb_info structure information */ fbi->var.xres = fbi->var.xres_virtual = MXCFB_SCREEN_WIDTH; fbi->var.yres = fbi->var.yres_virtual = MXCFB_SCREEN_HEIGHT; fbi->var.activate = FB_ACTIVATE_NOW; mxcfb_check_var(&fbi->var, fbi); mxcfb_set_fix(fbi); fbi->fbops = ops; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->pseudo_palette = mxcfbi->pseudo_palette; /* * Allocate colormap */ fb_alloc_cmap(&fbi->cmap, 16, 0); return fbi; }
static int __devinit milkymistfb_probe(struct platform_device *pdev) { struct milkymistfb *milkymistfb; struct fb_info *info; int ret = -ENOMEM; info = framebuffer_alloc(sizeof(*milkymistfb), &pdev->dev); if (!info) return -ENOMEM; info->fbops = &milkymistfb_ops; milkymistfb = info->par; milkymistfb->fb = info; fb_find_mode(&info->var, info, milkymistfb_mode_option, milkymist_modedb, ARRAY_SIZE(milkymist_modedb), NULL, 16); /* milkymistfb->vidmem = dma_alloc_coherent(&pdev->dev, videomemorysize, &milkymistfb->vidmem_phys, GFP_KERNEL);*/ milkymistfb->vidmem = vmalloc(videomemorysize); milkymistfb->vidmem_phys = (unsigned int)milkymistfb->vidmem; if (!milkymistfb->vidmem) { ret = -ENOMEM; goto err_framebuffer_release; } memset(milkymistfb->vidmem, 0, videomemorysize); info->screen_base = milkymistfb->vidmem; info->fix = milkymistfb_fix; info->pseudo_palette = milkymistfb->pseudo_palette; info->flags = FBINFO_FLAG_DEFAULT; info->fix.smem_start = milkymistfb->vidmem_phys; info->fix.smem_len = videomemorysize; ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret < 0) goto err_dma_free; ret = register_framebuffer(info); if (ret < 0) goto err_dealloc_cmap; platform_set_drvdata(pdev, milkymistfb); dev_info(&pdev->dev, "fb%d: Milkymist frame buffer at %p, size %ld k\n", info->node, milkymistfb->vidmem, videomemorysize >> 10); return 0; err_dealloc_cmap: fb_dealloc_cmap(&info->cmap); err_dma_free: /* dma_free_coherent(&pdev->dev, videomemorysize, milkymistfb->vidmem, milkymistfb->vidmem_phys);*/ vfree(milkymistfb->vidmem); err_framebuffer_release: framebuffer_release(info); return ret; }
static void setup_fb_info(struct sprdfb_device *dev) { struct fb_info *fb = dev->fb; struct panel_spec *panel = dev->panel; int r; fb->fbops = &sprdfb_ops; fb->flags = FBINFO_DEFAULT; /* finish setting up the fb_info struct */ strncpy(fb->fix.id, "sc8810fb", 16); fb->fix.ypanstep = 1; fb->fix.type = FB_TYPE_PACKED_PIXELS; fb->fix.visual = FB_VISUAL_TRUECOLOR; fb->fix.line_length = panel->width * dev->bpp / 8; fb->var.xres = panel->width; fb->var.yres = panel->height; fb->var.width = panel->width; fb->var.height = panel->height; fb->var.xres_virtual = panel->width; fb->var.yres_virtual = panel->height * FRAMEBUFFER_NR; fb->var.bits_per_pixel = dev->bpp; if(0 != dev->panel->fps){ fb->var.pixclock = (1000 * 1000 * 1000) / (dev->panel->fps * panel->width * panel->height) * 1000; }else{ fb->var.pixclock = (1000 * 1000 * 1000) / (SPRDFB_DEFAULT_FPS * panel->width * panel->height) * 1000; } fb->var.accel_flags = 0; fb->var.yoffset = 0; /* only support two pixel format */ if (dev->bpp == 32) { /* ABGR */ fb->var.red.offset = 24; fb->var.red.length = 8; fb->var.red.msb_right = 0; fb->var.green.offset = 16; fb->var.green.length = 8; fb->var.green.msb_right = 0; fb->var.blue.offset = 8; fb->var.blue.length = 8; fb->var.blue.msb_right = 0; } else { fb->var.red.offset = 11; fb->var.red.length = 5; fb->var.red.msb_right = 0; fb->var.green.offset = 5; fb->var.green.length = 6; fb->var.green.msb_right = 0; fb->var.blue.offset = 0; fb->var.blue.length = 5; fb->var.blue.msb_right = 0; } r = fb_alloc_cmap(&fb->cmap, 16, 0); fb->pseudo_palette = PP; PP[0] = 0; for (r = 1; r < 16; r++) PP[r] = 0xffffffff; }
int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) { int rc, size = cmap->len * sizeof(u16); struct fb_cmap umap; memset(&umap, 0, sizeof(struct fb_cmap)); rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); if (rc) return rc; if (copy_from_user(umap.red, cmap->red, size) || copy_from_user(umap.green, cmap->green, size) || copy_from_user(umap.blue, cmap->blue, size) || (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { rc = -EFAULT; goto out; } umap.start = cmap->start; if (!lock_fb_info(info)) { rc = -ENODEV; goto out; } if (cmap->start < 0 || (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)) { rc = -EINVAL; goto out1; } rc = fb_set_cmap(&umap, info); out1: unlock_fb_info(info); out: fb_dealloc_cmap(&umap); return rc; }
int fbgen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) { struct fb_info_gen *info2 = (struct fb_info_gen *)info; int err; int oldxres, oldyres, oldbpp, oldxres_virtual, oldyres_virtual, oldyoffset; if ((err = fbgen_do_set_var(var, con == currcon, info2))) return err; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { oldxres = fb_display[con].var.xres; oldyres = fb_display[con].var.yres; oldxres_virtual = fb_display[con].var.xres_virtual; oldyres_virtual = fb_display[con].var.yres_virtual; oldbpp = fb_display[con].var.bits_per_pixel; oldyoffset = fb_display[con].var.yoffset; fb_display[con].var = *var; if (oldxres != var->xres || oldyres != var->yres || oldxres_virtual != var->xres_virtual || oldyres_virtual != var->yres_virtual || oldbpp != var->bits_per_pixel || oldyoffset != var->yoffset) { fbgen_set_disp(con, info2); if (info->changevar) (*info->changevar)(con); if ((err = fb_alloc_cmap(&fb_display[con].cmap, 0, 0))) return err; fbgen_install_cmap(con, info2); } } var->activate = 0; return 0; }
static int alloc_cmap(struct jz_fb_win_info *win, unsigned int bpp) { int rv; switch (bpp) { case 1: rv = fb_alloc_cmap(&win->fb.cmap, 4, 0); break; case 2: rv = fb_alloc_cmap(&win->fb.cmap, 8, 0); break; case 4: rv = fb_alloc_cmap(&win->fb.cmap, 32, 0); break; case 8: default: rv = fb_alloc_cmap(&win->fb.cmap, 256, 0); break; } return rv; }
int __init maxinefb_init(void) { unsigned long fboff; unsigned long fb_start; int i; if (fb_get_options("maxinefb", NULL)) return -ENODEV; /* Validate we're on the proper machine type */ if (mips_machtype != MACH_DS5000_XX) { return -EINVAL; } ; ; /* Framebuffer display memory base address */ fb_start = DS5000_xx_ONBOARD_FBMEM_START; /* Clear screen */ for (fboff = fb_start; fboff < fb_start + 0x1ffff; fboff++) *(volatile unsigned char *)fboff = 0x0; maxinefb_fix.smem_start = fb_start; /* erase hardware cursor */ for (i = 0; i < 512; i++) { maxinefb_ims332_write_register(IMS332_REG_CURSOR_RAM + i, 0); /* if (i&0x8 == 0) maxinefb_ims332_write_register (IMS332_REG_CURSOR_RAM + i, 0x0f); else maxinefb_ims332_write_register (IMS332_REG_CURSOR_RAM + i, 0xf0); */ } fb_info.fbops = &maxinefb_ops; fb_info.screen_base = (char *)maxinefb_fix.smem_start; fb_info.var = maxinefb_defined; fb_info.fix = maxinefb_fix; fb_info.flags = FBINFO_DEFAULT; fb_alloc_cmap(&fb_info.cmap, 256, 0); if (register_framebuffer(&fb_info) < 0) return 1; return 0; }
/*! * @brief Initialize framebuffer information structure. * * @param info framebuffer information pointer * @param pdev pointer to struct device * @return Negative errno on error, or zero on success. */ static int __init _init_fbinfo(struct fb_info *info, struct platform_device *pdev) { struct mx2fb_info *mx2fbi = (struct mx2fb_info *)info->par; info->device = &pdev->dev; info->var.activate = FB_ACTIVATE_NOW; info->fbops = &mx2fb_ops; info->flags = FBINFO_FLAG_DEFAULT; info->pseudo_palette = &mx2fbi->pseudo_palette; /* Allocate colormap */ fb_alloc_cmap(&info->cmap, 16, 0); return 0; }
static void init_chips(struct fb_info *p, unsigned long addr) { memset(p->screen_base, 0, 0x100000); p->fix = chipsfb_fix; p->fix.smem_start = addr; p->var = chipsfb_var; p->fbops = &chipsfb_ops; p->flags = FBINFO_DEFAULT; fb_alloc_cmap(&p->cmap, 256, 0); chips_hw_init(); }
static int gxfb_set_par(struct fb_info *info) { if (info->var.bits_per_pixel > 8) { info->fix.visual = FB_VISUAL_TRUECOLOR; fb_dealloc_cmap(&info->cmap); } else { info->fix.visual = FB_VISUAL_PSEUDOCOLOR; fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); } info->fix.line_length = gx_line_delta(info->var.xres, info->var.bits_per_pixel); gx_set_mode(info); return 0; }
static int vfb_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, vfb_setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { struct fb_info_gen *info2 = (struct fb_info_gen *)info; struct fbgen_hwswitch *fbhw = info2->fbhw; int err; if (!fb_display[con].cmap.len) { /* no colormap allocated ? */ int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256; if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0))) return err; } if (con == currcon) /* current console ? */ return fb_set_cmap(cmap, kspc, fbhw->setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
static int igafb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { int err; struct fb_info_iga *fb = (struct fb_info_iga*) info; if (!fb_display[con].cmap.len) { /* no colormap allocated? */ err = fb_alloc_cmap(&fb_display[con].cmap, fb->video_cmap_len,0); if (err) return err; } if (con == fb->currcon) /* current console? */ return fb_set_cmap(cmap, kspc, iga_setcolreg, info); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
static int gx1fb_set_par(struct fb_info *info) { struct geodefb_par *par = info->par; if (info->var.bits_per_pixel == 16) { info->fix.visual = FB_VISUAL_TRUECOLOR; fb_dealloc_cmap(&info->cmap); } else { info->fix.visual = FB_VISUAL_PSEUDOCOLOR; fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); } info->fix.line_length = gx1_line_delta(info->var.xres, info->var.bits_per_pixel); par->dc_ops->set_mode(info); return 0; }
static int __init q40fb_probe(struct device *device) { struct platform_device *dev = to_platform_device(device); struct fb_info *info; if (!MACH_IS_Q40) return -ENXIO; /* mapped in q40/config.c */ q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR; info = framebuffer_alloc(sizeof(u32) * 256, &dev->dev); if (!info) return -ENOMEM; info->var = q40fb_var; info->fix = q40fb_fix; info->fbops = &q40fb_ops; info->flags = FBINFO_FLAG_DEFAULT; /* not as module for now */ info->pseudo_palette = info->par; info->par = NULL; info->screen_base = (char *) q40fb_fix.smem_start; if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { framebuffer_release(info); return -ENOMEM; } master_outb(3, DISPLAY_CONTROL_REG); if (register_framebuffer(info) < 0) { printk(KERN_ERR "Unable to register Q40 frame buffer\n"); fb_dealloc_cmap(&info->cmap); framebuffer_release(info); return -EINVAL; } printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n", info->node); return 0; }
int altvipfb2_probe(struct device *dev, void __iomem *base) { int retval; void *fbmem_virt; struct altvipfb2_priv *fbpriv = dev_get_drvdata(dev); fbmem_virt = dma_alloc_coherent(NULL, fbpriv->info.fix.smem_len, (void *)&fbpriv->info.fix.smem_start, GFP_KERNEL); if (!fbmem_virt) { dev_err(dev, "altvipfb2: unable to allocate %d Bytes fb memory\n", fbpriv->info.fix.smem_len); return -ENOMEM; } fbpriv->info.screen_base = (char *)fbmem_virt; retval = fb_alloc_cmap(&fbpriv->info.cmap, PALETTE_SIZE, 0); if (retval < 0) goto err_dma_free; altvipfb2_setup_fb_info(fbpriv); altvipfb2_start_hw(base, &fbpriv->info); dev_info(dev, "fb%d: %s frame buffer device at 0x%x+0x%x\n", fbpriv->info.node, fbpriv->info.fix.id, (unsigned int)fbpriv->info.fix.smem_start, fbpriv->info.fix.smem_len); return register_framebuffer(&fbpriv->info); err_dma_free: fb_dealloc_cmap(&fbpriv->info.cmap); dma_free_coherent(NULL, fbpriv->info.fix.smem_len, fbmem_virt, fbpriv->info.fix.smem_start); return retval; }
/** * fbgen_set_var - set the user defined part of display * @var: fb_var_screeninfo user defined part of the display * @con: virtual console number * @info: frame buffer info structure * * Set the user defined part of the display as dictated by @var * for virtual console @con on device @info. * * Returns negative errno on error, or zero for success. * */ int fbgen_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info) { struct fb_bitfield oldred, oldgreen, oldblue, oldalpha; int oldbpp, err; if (memcmp(&info->var, var, sizeof(var)) || con < 0) { if ((err = info->fbops->fb_check_var(var, info))) return err; if (var->activate & FB_ACTIVATE_ALL) info->disp->var = *var; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { oldbpp = info->var.bits_per_pixel; oldred = info->var.red; oldblue = info->var.blue; oldgreen = info->var.green; oldalpha = info->var.transp; if (info->fbops->fb_set_par) info->fbops->fb_set_par(info); info->var = *var; fbgen2_set_disp(con, info); if (info->changevar) (*info->changevar)(con); if (oldbpp != var->bits_per_pixel || memcmp(&oldred,&info->var.red,sizeof(oldred)) || memcmp(&oldgreen,&info->var.green,sizeof(oldgreen)) || memcmp(&oldblue, &info->var.blue, sizeof(oldblue)) || memcmp(&oldalpha,&info->var.transp,sizeof(oldalpha))){ if ((err = fb_alloc_cmap(&info->cmap, 0, 0))) return err; fb_set_cmap(&info->cmap, 1, info->fbops->fb_setcolreg, info); } } var->activate = 0; } return 0; }
static void __init init_chips(struct fb_info *p, unsigned long addr) { p->fix = chipsfb_fix; p->fix.smem_start = addr; p->var = chipsfb_var; p->fbops = &chipsfb_ops; p->flags = FBINFO_DEFAULT; fb_alloc_cmap(&p->cmap, 256, 0); if (register_framebuffer(p) < 0) { printk(KERN_ERR "C&T 65550 framebuffer failed to register\n"); return; } printk(KERN_INFO "fb%d: Chips 65550 frame buffer (%dK RAM detected)\n", p->node, p->fix.smem_len / 1024); chips_hw_init(); }
static int sun3fb_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 == info->currcon) { /* current console? */ err = fb_set_cmap(cmap, kspc, info); if (!err) { struct fb_info_sbusfb *fb = sbusfbinfo(info); if (fb->loadcmap) (*fb->loadcmap)(fb, &fb_display[con], cmap->start, cmap->len); } return err; } else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0; }
int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info) { struct fb_cmap *dcmap; int err = 0; if (con == info->currcon) dcmap = &info->cmap; else dcmap = &fb_display[con].cmap; /* no colormap allocated? */ if (!dcmap->len) err = fb_alloc_cmap(dcmap, 256, 0); if (!err && con == info->currcon) err = fb_set_cmap(cmap, kspc, info->fbops->fb_setcolreg, info); if (!err) fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1); return err; }
static int __init init_vals(struct fb_info *info) { struct fb_var_screeninfo *var = &info->var; struct fb_fix_screeninfo *fix = &info->fix; var->xres = 240; var->yres = 320; var->xres_virtual = 240; var->yres_virtual = 320; var->xoffset = 0; var->yoffset = 0; var->bits_per_pixel = 16; var->grayscale = 0; 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->activate = FB_ACTIVATE_NOW; var->height = -1; var->width = -1; var->vmode = FB_VMODE_NONINTERLACED; var->rotate = 0; strcpy(fix->id, "STM32 VFB"); fix->type = FB_TYPE_PACKED_PIXELS; fix->visual = FB_VISUAL_TRUECOLOR; fix->xpanstep = 0; fix->ypanstep = 1; fix->ywrapstep = 0; fix->line_length = var->xres_virtual * (var->bits_per_pixel / 8); fix->accel = FB_ACCEL_NONE; return fb_alloc_cmap(&(info->cmap), 256, 0); }
int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) { int rc, size = cmap->len * sizeof(u16); struct fb_cmap umap; if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap) return -EINVAL; memset(&umap, 0, sizeof(struct fb_cmap)); rc = fb_alloc_cmap(&umap, cmap->len, cmap->transp != NULL); if (rc) return rc; if (copy_from_user(umap.red, cmap->red, size) || copy_from_user(umap.green, cmap->green, size) || copy_from_user(umap.blue, cmap->blue, size) || (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { fb_dealloc_cmap(&umap); return -EFAULT; } umap.start = cmap->start; rc = fb_set_cmap(&umap, info); fb_dealloc_cmap(&umap); return rc; }
/** * s3c_fb_probe_win() - register an hardware window * @sfb: The base resources for the hardware * @res: Pointer to where to place the resultant window. * * Allocate and do the basic initialisation for one of the hardware's graphics * windows. */ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, struct s3c_fb_win **res) { struct fb_var_screeninfo *var; struct fb_videomode *initmode; struct s3c_fb_pd_win *windata; struct s3c_fb_win *win; struct fb_info *fbinfo; int palette_size; int ret; dev_dbg(sfb->dev, "probing window %d\n", win_no); palette_size = s3c_fb_win_pal_size(win_no); fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) + palette_size * sizeof(u32), sfb->dev); if (!fbinfo) { dev_err(sfb->dev, "failed to allocate framebuffer\n"); return -ENOENT; } windata = sfb->pdata->win[win_no]; initmode = &windata->win_mode; WARN_ON(windata->max_bpp == 0); WARN_ON(windata->win_mode.xres == 0); WARN_ON(windata->win_mode.yres == 0); win = fbinfo->par; var = &fbinfo->var; win->fbinfo = fbinfo; win->parent = sfb; win->windata = windata; win->index = win_no; win->palette_buffer = (u32 *)(win + 1); ret = s3c_fb_alloc_memory(sfb, win); if (ret) { dev_err(sfb->dev, "failed to allocate display memory\n"); return ret; } /* setup the r/b/g positions for the window's palette */ s3c_fb_init_palette(win_no, &win->palette); /* setup the initial video mode from the window */ fb_videomode_to_var(&fbinfo->var, initmode); fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; fbinfo->fix.accel = FB_ACCEL_NONE; fbinfo->var.activate = FB_ACTIVATE_NOW; fbinfo->var.vmode = FB_VMODE_NONINTERLACED; fbinfo->var.bits_per_pixel = windata->default_bpp; fbinfo->fbops = &s3c_fb_ops; fbinfo->flags = FBINFO_FLAG_DEFAULT; fbinfo->pseudo_palette = &win->pseudo_palette; /* prepare to actually start the framebuffer */ ret = s3c_fb_check_var(&fbinfo->var, fbinfo); if (ret < 0) { dev_err(sfb->dev, "check_var failed on initial video params\n"); return ret; } /* create initial colour map */ ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1); if (ret == 0) fb_set_cmap(&fbinfo->cmap, fbinfo); else dev_err(sfb->dev, "failed to allocate fb cmap\n"); s3c_fb_set_par(fbinfo); dev_dbg(sfb->dev, "about to register framebuffer\n"); /* run the check_var and set_par on our configuration. */ ret = register_framebuffer(fbinfo); if (ret < 0) { dev_err(sfb->dev, "failed to register framebuffer\n"); return ret; } *res = win; dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); return 0; }
static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) { struct fb_info *info; struct sh_mobile_lcdc_priv *priv; struct sh_mobile_lcdc_info *pdata = pdev->dev.platform_data; struct resource *res; int error; void *buf; int i, j; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); i = platform_get_irq(pdev, 0); if (!res || i < 0) { dev_err(&pdev->dev, "cannot get platform resources\n"); return -ENOENT; } priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "cannot allocate device data\n"); return -ENOMEM; } platform_set_drvdata(pdev, priv); error = request_irq(i, sh_mobile_lcdc_irq, IRQF_DISABLED, dev_name(&pdev->dev), priv); if (error) { dev_err(&pdev->dev, "unable to request irq\n"); goto err1; } priv->irq = i; atomic_set(&priv->hw_usecnt, -1); j = 0; for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) { struct sh_mobile_lcdc_chan *ch = priv->ch + j; ch->lcdc = priv; memcpy(&ch->cfg, &pdata->ch[i], sizeof(pdata->ch[i])); error = sh_mobile_lcdc_check_interface(ch); if (error) { dev_err(&pdev->dev, "unsupported interface type\n"); goto err1; } init_waitqueue_head(&ch->frame_end_wait); init_completion(&ch->vsync_completion); ch->pan_offset = 0; /* probe the backlight is there is one defined */ if (ch->cfg.bl_info.max_brightness) ch->bl = sh_mobile_lcdc_bl_probe(&pdev->dev, ch); switch (pdata->ch[i].chan) { case LCDC_CHAN_MAINLCD: ch->enabled = 1 << 1; ch->reg_offs = lcdc_offs_mainlcd; j++; break; case LCDC_CHAN_SUBLCD: ch->enabled = 1 << 2; ch->reg_offs = lcdc_offs_sublcd; j++; break; } } if (!j) { dev_err(&pdev->dev, "no channels defined\n"); error = -EINVAL; goto err1; } /* for dual channel LCDC (MAIN + SUB) force shared bpp setting */ if (j == 2) priv->forced_bpp = pdata->ch[0].bpp; priv->base = ioremap_nocache(res->start, resource_size(res)); if (!priv->base) goto err1; error = sh_mobile_lcdc_setup_clocks(pdev, pdata->clock_source, priv); if (error) { dev_err(&pdev->dev, "unable to setup clocks\n"); goto err1; } priv->meram_dev = pdata->meram_dev; for (i = 0; i < j; i++) { struct fb_var_screeninfo *var; const struct fb_videomode *lcd_cfg, *max_cfg = NULL; struct sh_mobile_lcdc_chan *ch = priv->ch + i; struct sh_mobile_lcdc_chan_cfg *cfg = &ch->cfg; const struct fb_videomode *mode = cfg->lcd_cfg; unsigned long max_size = 0; int k; int num_cfg; ch->info = framebuffer_alloc(0, &pdev->dev); if (!ch->info) { dev_err(&pdev->dev, "unable to allocate fb_info\n"); error = -ENOMEM; break; } info = ch->info; var = &info->var; info->fbops = &sh_mobile_lcdc_ops; info->par = ch; mutex_init(&ch->open_lock); for (k = 0, lcd_cfg = mode; k < cfg->num_cfg && lcd_cfg; k++, lcd_cfg++) { unsigned long size = lcd_cfg->yres * lcd_cfg->xres; /* NV12 buffers must have even number of lines */ if ((cfg->nonstd) && cfg->bpp == 12 && (lcd_cfg->yres & 0x1)) { dev_err(&pdev->dev, "yres must be multiple of 2" " for YCbCr420 mode.\n"); error = -EINVAL; goto err1; } if (size > max_size) { max_cfg = lcd_cfg; max_size = size; } } if (!mode) max_size = MAX_XRES * MAX_YRES; else if (max_cfg) dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", max_cfg->xres, max_cfg->yres); info->fix = sh_mobile_lcdc_fix; info->fix.smem_len = max_size * 2 * cfg->bpp / 8; /* Only pan in 2 line steps for NV12 */ if (cfg->nonstd && cfg->bpp == 12) info->fix.ypanstep = 2; if (!mode) { mode = &default_720p; num_cfg = 1; } else { num_cfg = cfg->num_cfg; } fb_videomode_to_modelist(mode, num_cfg, &info->modelist); fb_videomode_to_var(var, mode); var->width = cfg->lcd_size_cfg.width; var->height = cfg->lcd_size_cfg.height; /* Default Y virtual resolution is 2x panel size */ var->yres_virtual = var->yres * 2; var->activate = FB_ACTIVATE_NOW; error = sh_mobile_lcdc_set_bpp(var, cfg->bpp, cfg->nonstd); if (error) break; buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, &ch->dma_handle, GFP_KERNEL); if (!buf) { dev_err(&pdev->dev, "unable to allocate buffer\n"); error = -ENOMEM; break; } info->pseudo_palette = &ch->pseudo_palette; info->flags = FBINFO_FLAG_DEFAULT; error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); if (error < 0) { dev_err(&pdev->dev, "unable to allocate cmap\n"); dma_free_coherent(&pdev->dev, info->fix.smem_len, buf, ch->dma_handle); break; } info->fix.smem_start = ch->dma_handle; if (var->nonstd) info->fix.line_length = var->xres; else info->fix.line_length = var->xres * (cfg->bpp / 8); info->screen_base = buf; info->device = &pdev->dev; ch->display_var = *var; } if (error) goto err1; error = sh_mobile_lcdc_start(priv); if (error) { dev_err(&pdev->dev, "unable to start hardware\n"); goto err1; } for (i = 0; i < j; i++) { struct sh_mobile_lcdc_chan *ch = priv->ch + i; info = ch->info; if (info->fbdefio) { ch->sglist = vmalloc(sizeof(struct scatterlist) * info->fix.smem_len >> PAGE_SHIFT); if (!ch->sglist) { dev_err(&pdev->dev, "cannot allocate sglist\n"); goto err1; } } info->bl_dev = ch->bl; error = register_framebuffer(info); if (error < 0) goto err1; dev_info(info->dev, "registered %s/%s as %dx%d %dbpp.\n", pdev->name, (ch->cfg.chan == LCDC_CHAN_MAINLCD) ? "mainlcd" : "sublcd", info->var.xres, info->var.yres, ch->cfg.bpp); /* deferred io mode: disable clock to save power */ if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED) sh_mobile_lcdc_clk_off(priv); }
static int vdmafb_probe(struct platform_device *pdev) { int ret = 0; struct vdmafb_dev *fbdev; struct resource *res; int fbsize; struct backlight_properties props; struct backlight_device *bl; fbdev = devm_kzalloc(&pdev->dev, sizeof(*fbdev), GFP_KERNEL); if (!fbdev) return -ENOMEM; platform_set_drvdata(pdev, fbdev); fbdev->info.fbops = &vdmafb_ops; fbdev->info.device = &pdev->dev; fbdev->info.par = fbdev; fbdev->dma_template = devm_kzalloc(&pdev->dev, sizeof(struct dma_interleaved_template) + sizeof(struct data_chunk), GFP_KERNEL); if (!fbdev->dma_template) return -ENOMEM; vdmafb_init_var(fbdev, pdev); vdmafb_init_fix(fbdev); /* Request I/O resource */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "I/O resource request failed\n"); return -ENXIO; } res->flags &= ~IORESOURCE_CACHEABLE; fbdev->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(fbdev->regs)) return PTR_ERR(fbdev->regs); /* Allocate framebuffer memory */ fbsize = fbdev->info.fix.smem_len; fbdev->fb_virt = dma_alloc_coherent(&pdev->dev, PAGE_ALIGN(fbsize), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_virt) { dev_err(&pdev->dev, "Frame buffer memory allocation failed\n"); return -ENOMEM; } fbdev->info.fix.smem_start = fbdev->fb_phys; fbdev->info.screen_base = fbdev->fb_virt; fbdev->info.pseudo_palette = fbdev->pseudo_palette; pr_debug("%s virt=%p phys=%x size=%d\n", __func__, fbdev->fb_virt, fbdev->fb_phys, fbsize); /* Clear framebuffer */ memset_io(fbdev->fb_virt, 0, fbsize); fbdev->dma = dma_request_slave_channel(&pdev->dev, "video"); if (IS_ERR_OR_NULL(fbdev->dma)) { dev_err(&pdev->dev, "Failed to allocate DMA channel (%d).\n", ret); if (fbdev->dma) ret = PTR_ERR(fbdev->dma); else ret = -EPROBE_DEFER; goto err_dma_free; } /* Setup and enable the framebuffer */ vdmafb_setupfb(fbdev); ret = fb_alloc_cmap(&fbdev->info.cmap, 256, 0); if (ret) { dev_err(&pdev->dev, "fb_alloc_cmap failed\n"); } /* Register framebuffer */ ret = register_framebuffer(&fbdev->info); if (ret) { dev_err(&pdev->dev, "Framebuffer registration failed\n"); goto err_channel_free; } /* Register backlight */ memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = 1023; bl = backlight_device_register("backlight", &pdev->dev, fbdev, &vdmafb_bl_ops, &props); if (IS_ERR(bl)) { dev_err(&pdev->dev, "error %ld on backlight register\n", PTR_ERR(bl)); } else { fbdev->backlight = bl; bl->props.power = FB_BLANK_UNBLANK; bl->props.fb_blank = FB_BLANK_UNBLANK; bl->props.brightness = vdmafb_bl_get_brightness(bl); } return 0; err_channel_free: dma_release_channel(fbdev->dma); err_dma_free: dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbsize), fbdev->fb_virt, fbdev->fb_phys); return ret; }
static void __init offb_init_fb(const char *name, const char *full_name, int width, int height, int depth, int pitch, unsigned long address, int foreign_endian, struct device_node *dp) { unsigned long res_size = pitch * height * (depth + 7) / 8; struct offb_par *par = &default_par; unsigned long res_start = address; struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; struct fb_info *info; if (!request_mem_region(res_start, res_size, "offb")) return; printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", width, height, name, address, depth, pitch); if (depth != 8 && depth != 15 && depth != 16 && depth != 32) { printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth); release_mem_region(res_start, res_size); return; } info = framebuffer_alloc(sizeof(u32) * 16, NULL); if (info == 0) { release_mem_region(res_start, res_size); return; } fix = &info->fix; var = &info->var; info->par = par; strcpy(fix->id, "OFfb "); strncat(fix->id, name, sizeof(fix->id) - sizeof("OFfb ")); fix->id[sizeof(fix->id) - 1] = '\0'; var->xres = var->xres_virtual = width; var->yres = var->yres_virtual = height; fix->line_length = pitch; fix->smem_start = address; fix->smem_len = pitch * height; fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; par->cmap_type = cmap_unknown; if (depth == 8) offb_init_palette_hacks(info, dp, name, address); else fix->visual = FB_VISUAL_TRUECOLOR; var->xoffset = var->yoffset = 0; switch (depth) { case 8: var->bits_per_pixel = 8; var->red.offset = 0; var->red.length = 8; var->green.offset = 0; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 0; var->transp.length = 0; break; case 15: /* RGB 555 */ var->bits_per_pixel = 16; var->red.offset = 10; var->red.length = 5; var->green.offset = 5; var->green.length = 5; var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case 16: /* RGB 565 */ var->bits_per_pixel = 16; 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 = 0; var->transp.length = 0; break; case 32: /* RGB 888 */ var->bits_per_pixel = 32; var->red.offset = 16; var->red.length = 8; var->green.offset = 8; var->green.length = 8; var->blue.offset = 0; var->blue.length = 8; var->transp.offset = 24; var->transp.length = 8; break; } var->red.msb_right = var->green.msb_right = var->blue.msb_right = var->transp.msb_right = 0; var->grayscale = 0; var->nonstd = 0; var->activate = 0; var->height = var->width = -1; var->pixclock = 10000; var->left_margin = var->right_margin = 16; var->upper_margin = var->lower_margin = 16; var->hsync_len = var->vsync_len = 8; var->sync = 0; var->vmode = FB_VMODE_NONINTERLACED; /* set offb aperture size for generic probing */ info->apertures = alloc_apertures(1); if (!info->apertures) goto out_aper; info->apertures->ranges[0].base = address; info->apertures->ranges[0].size = fix->smem_len; info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); info->pseudo_palette = (void *) (info + 1); info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE | foreign_endian; fb_alloc_cmap(&info->cmap, 256, 0); if (register_framebuffer(info) < 0) goto out_err; printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", info->node, full_name); return; out_err: iounmap(info->screen_base); out_aper: iounmap(par->cmap_adr); par->cmap_adr = NULL; framebuffer_release(info); release_mem_region(res_start, res_size); }
static int merrifield_fb_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int ret; struct fb_info *info = NULL; int fb_base = 0; int width = H_ACTIVE; int height = V_ACTIVE; ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "failed to enable device!\n"); goto failure; } info = framebuffer_alloc(0, &pdev->dev); if (!info) { dev_err(&pdev->dev, "framebuffer allocation failure.\n"); goto failure; } merrifield_fb_fix.mmio_start = pci_resource_start(pdev, 0); merrifield_fb_fix.mmio_len = pci_resource_len(pdev, 0); if (!request_mem_region(merrifield_fb_fix.mmio_start, merrifield_fb_fix.mmio_len, DRV_NAME)) { dev_err(&pdev->dev, "mmio request_mem_region failure!\n"); goto failure; } io_virt = ioremap_nocache(merrifield_fb_fix.mmio_start, merrifield_fb_fix.mmio_len); pci_read_config_dword(pdev, 0x5C, &fb_base); /* Allocate enough for up 2 x 16-bit frame buffers at * our given resolution which is used for double buffering */ merrifield_fb_fix.smem_start = fb_base; merrifield_fb_fix.smem_len = H_ACTIVE * V_ACTIVE * 4; info->screen_base = ioremap_nocache(merrifield_fb_fix.smem_start, merrifield_fb_fix.smem_len); info->fix = merrifield_fb_fix; info->fbops = &merrifield_fb_ops; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_DISABLED | FBINFO_FLAG_DEFAULT; strcat(info->fix.id, DRV_NAME); info->var.activate = FB_ACTIVATE_NOW; info->device = &pdev->dev; ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret < 0) { dev_err(&pdev->dev, "cmap allocation failure.\n"); goto failure; } /* RGB 5:6:5 */ info->pseudo_palette = &info->cmap; info->cmap.len = 16; info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; info->fix.line_length = width * 2; info->fix.accel = FB_ACCEL_NONE; info->fix.ypanstep = 1; info->fix.smem_start = merrifield_fb_fix.smem_start; info->fix.smem_len = merrifield_fb_fix.smem_len; info->var.xres = width; info->var.yres = height; info->var.xres_virtual = width; info->var.yres_virtual = height * 2; info->var.bits_per_pixel = 16; info->var.height = height; info->var.width = width; info->var.red.offset = 11; info->var.red.length = 5; info->var.green.offset = 5; info->var.green.length = 6; info->var.blue.offset = 0; info->var.blue.length = 5; ret = fb_set_var(info, &info->var); if (ret) { dev_err(&pdev->dev, "error setting var info\n"); goto failure; } info->pixmap.addr = kmalloc(4096, GFP_KERNEL); if (!info->pixmap.addr) { dev_err(&pdev->dev, "pixmap allocation failure\n"); goto failure; } info->pixmap.size = 4096; info->pixmap.buf_align = 4; info->pixmap.scan_align = 1; info->pixmap.access_align = 32; info->pixmap.flags = FB_PIXMAP_SYSTEM; pci_set_drvdata(pdev, info); if (register_framebuffer(info) < 0) { dev_err(&pdev->dev, "could not register framebuffer\n"); goto failure; } init_display_controller_registers(); return 0; failure: merrifield_fb_remove(pdev); return ret; }
static int __devinit fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id) { struct fb_info *info; unsigned long *ptr; int is_fm; int x, y; is_fm = z->id == ZORRO_PROD_BSC_FRAMEMASTER_II; if (!zorro_request_device(z,"fm2fb")) return -ENXIO; info = framebuffer_alloc(256 * sizeof(u32), &z->dev); if (!info) { zorro_release_device(z); return -ENOMEM; } if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { framebuffer_release(info); zorro_release_device(z); return -ENOMEM; } /* assigning memory to kernel space */ fb_fix.smem_start = zorro_resource_start(z); info->screen_base = ioremap(fb_fix.smem_start, FRAMEMASTER_SIZE); fb_fix.mmio_start = fb_fix.smem_start + FRAMEMASTER_REG; fm2fb_reg = (unsigned char *)(info->screen_base+FRAMEMASTER_REG); strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II"); /* make EBU color bars on display */ ptr = (unsigned long *)fb_fix.smem_start; for (y = 0; y < 576; y++) { for (x = 0; x < 96; x++) *ptr++ = 0xffffff;/* white */ for (x = 0; x < 96; x++) *ptr++ = 0xffff00;/* yellow */ for (x = 0; x < 96; x++) *ptr++ = 0x00ffff;/* cyan */ for (x = 0; x < 96; x++) *ptr++ = 0x00ff00;/* green */ for (x = 0; x < 96; x++) *ptr++ = 0xff00ff;/* magenta */ for (x = 0; x < 96; x++) *ptr++ = 0xff0000;/* red */ for (x = 0; x < 96; x++) *ptr++ = 0x0000ff;/* blue */ for (x = 0; x < 96; x++) *ptr++ = 0x000000;/* black */ } fm2fb_blank(0, info); if (fm2fb_mode == -1) fm2fb_mode = FM2FB_MODE_PAL; info->fbops = &fm2fb_ops; info->var = fb_var_modes[fm2fb_mode]; info->pseudo_palette = info->par; info->par = NULL; info->fix = fb_fix; info->flags = FBINFO_DEFAULT; if (register_framebuffer(info) < 0) { fb_dealloc_cmap(&info->cmap); framebuffer_release(info); zorro_release_device(z); return -EINVAL; } printk("fb%d: %s frame buffer device\n", info->node, fb_fix.id); return 0; }
static int __devinit hpfb_init_one(unsigned long phys_base, unsigned long virt_base) { unsigned long fboff, fb_width, fb_height, fb_start; fb_regs = virt_base; fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB); fb_info.fix.smem_start = (in_8(fb_regs + fboff) << 16); if (phys_base >= DIOII_BASE) { fb_info.fix.smem_start += phys_base; } if (DIO_SECID(fb_regs) != DIO_ID2_TOPCAT) { /* This is the magic incantation the HP X server uses to make Catseye boards work. */ while (in_be16(fb_regs+0x4800) & 1) ; out_be16(fb_regs+0x4800, 0); /* Catseye status */ out_be16(fb_regs+0x4510, 0); /* VB */ out_be16(fb_regs+0x4512, 0); /* TCNTRL */ out_be16(fb_regs+0x4514, 0); /* ACNTRL */ out_be16(fb_regs+0x4516, 0); /* PNCNTRL */ out_be16(fb_regs+0x4206, 0x90); /* RUG Command/Status */ out_be16(fb_regs+0x60a2, 0); /* Overlay Mask */ out_be16(fb_regs+0x60bc, 0); /* Ram Select */ } /* * Fill in the available video resolution */ fb_width = (in_8(fb_regs + HPFB_FBWMSB) << 8) | in_8(fb_regs + HPFB_FBWLSB); fb_info.fix.line_length = fb_width; fb_height = (in_8(fb_regs + HPFB_FBHMSB) << 8) | in_8(fb_regs + HPFB_FBHLSB); fb_info.fix.smem_len = fb_width * fb_height; fb_start = (unsigned long)ioremap_writethrough(fb_info.fix.smem_start, fb_info.fix.smem_len); hpfb_defined.xres = (in_8(fb_regs + HPFB_DWMSB) << 8) | in_8(fb_regs + HPFB_DWLSB); hpfb_defined.yres = (in_8(fb_regs + HPFB_DHMSB) << 8) | in_8(fb_regs + HPFB_DHLSB); hpfb_defined.xres_virtual = hpfb_defined.xres; hpfb_defined.yres_virtual = hpfb_defined.yres; hpfb_defined.bits_per_pixel = in_8(fb_regs + HPFB_NUMPLANES); printk(KERN_INFO "hpfb: framebuffer at 0x%lx, mapped to 0x%lx, size %dk\n", fb_info.fix.smem_start, fb_start, fb_info.fix.smem_len/1024); printk(KERN_INFO "hpfb: mode is %dx%dx%d, linelength=%d\n", hpfb_defined.xres, hpfb_defined.yres, hpfb_defined.bits_per_pixel, fb_info.fix.line_length); /* * Give the hardware a bit of a prod and work out how many bits per * pixel are supported. */ out_8(fb_regs + TC_WEN, 0xff); out_8(fb_regs + TC_PRR, RR_COPY); out_8(fb_regs + TC_FBEN, 0xff); out_8(fb_start, 0xff); fb_bitmask = in_8(fb_start); out_8(fb_start, 0); /* * Enable reading/writing of all the planes. */ out_8(fb_regs + TC_WEN, fb_bitmask); out_8(fb_regs + TC_PRR, RR_COPY); out_8(fb_regs + TC_REN, fb_bitmask); out_8(fb_regs + TC_FBEN, fb_bitmask); /* * Clear the screen. */ topcat_blit(0, 0, 0, 0, fb_width, fb_height, RR_CLEAR); /* * Let there be consoles.. */ if (DIO_SECID(fb_regs) == DIO_ID2_TOPCAT) strcat(fb_info.fix.id, "Topcat"); else strcat(fb_info.fix.id, "Catseye"); fb_info.fbops = &hpfb_ops; fb_info.flags = FBINFO_DEFAULT; fb_info.var = hpfb_defined; fb_info.screen_base = (char *)fb_start; fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0); if (register_framebuffer(&fb_info) < 0) { fb_dealloc_cmap(&fb_info.cmap); iounmap(fb_info.screen_base); fb_info.screen_base = NULL; return 1; } printk(KERN_INFO "fb%d: %s frame buffer device\n", fb_info.node, fb_info.fix.id); return 0; }
static int mxc_elcdif_fb_probe(struct platform_device *pdev) { int ret = 0; struct mxc_elcdif_fb_data *data; struct resource *res; struct fb_info *fbi; struct mxc_fb_platform_data *pdata = pdev->dev.platform_data; fbi = framebuffer_alloc(sizeof(struct mxc_elcdif_fb_data), &pdev->dev); if (fbi == NULL) { ret = -ENOMEM; goto out; } data = (struct mxc_elcdif_fb_data *)fbi->par; data->cur_blank = data->next_blank = FB_BLANK_UNBLANK; fbi->var.activate = FB_ACTIVATE_NOW; fbi->fbops = &mxc_elcdif_fb_ops; fbi->flags = FBINFO_FLAG_DEFAULT; fbi->pseudo_palette = data->pseudo_palette; ret = fb_alloc_cmap(&fbi->cmap, 16, 0); if (ret) goto out; g_elcdif_dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "cannot get IRQ resource\n"); ret = -ENODEV; goto err0; } data->dma_irq = res->start; ret = request_irq(data->dma_irq, lcd_irq_handler, 0, "mxc_elcdif_fb", data); if (ret) { dev_err(&pdev->dev, "request_irq (%d) failed with error %d\n", data->dma_irq, ret); goto err0; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { ret = -ENODEV; goto err1; } elcdif_base = ioremap(res->start, SZ_4K); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (res) { fbi->fix.smem_len = res->end - res->start + 1; fbi->fix.smem_start = res->start; fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len); } strcpy(fbi->fix.id, "mxc_elcdif_fb"); fbi->var.xres = 800; fbi->var.yres = 480; if (pdata && !data->output_pix_fmt) data->output_pix_fmt = pdata->interface_pix_fmt; if (pdata && pdata->mode && pdata->num_modes) fb_videomode_to_modelist(pdata->mode, pdata->num_modes, &fbi->modelist); if (!fb_mode && pdata && pdata->mode_str) fb_mode = pdata->mode_str; if (fb_mode) { ret = fb_find_mode(&fbi->var, fbi, fb_mode, NULL, 0, NULL, default_bpp); if ((!ret || (ret > 2)) && pdata && pdata->mode && pdata->num_modes) fb_find_mode(&fbi->var, fbi, fb_mode, pdata->mode, pdata->num_modes, NULL, default_bpp); } mxc_elcdif_fb_check_var(&fbi->var, fbi); fbi->var.xres_virtual = fbi->var.xres; fbi->var.yres_virtual = fbi->var.yres * 3; mxc_elcdif_fb_set_fix(fbi); if (!res || !res->end) if (mxc_elcdif_fb_map_video_memory(fbi) < 0) { ret = -ENOMEM; goto err2; } g_elcdif_axi_clk = clk_get(g_elcdif_dev, "elcdif_axi"); if (g_elcdif_axi_clk == NULL) { dev_err(&pdev->dev, "can't get ELCDIF axi clk\n"); ret = -ENODEV; goto err3; } g_elcdif_pix_clk = clk_get(g_elcdif_dev, "elcdif_pix"); if (g_elcdif_pix_clk == NULL) { dev_err(&pdev->dev, "can't get ELCDIF pix clk\n"); ret = -ENODEV; goto err3; } /* * Set an appropriate pixel clk rate first, so that we can * access ELCDIF registers. */ clk_set_rate(g_elcdif_pix_clk, 25000000); ret = register_framebuffer(fbi); if (ret) goto err3; platform_set_drvdata(pdev, fbi); return 0; err3: mxc_elcdif_fb_unmap_video_memory(fbi); err2: iounmap(elcdif_base); err1: free_irq(data->dma_irq, data); err0: fb_dealloc_cmap(&fbi->cmap); framebuffer_release(fbi); out: return ret; }