static int __devinit chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent) { struct fb_info *p; unsigned long addr, size; unsigned short cmd; int rc = -ENODEV; if (pci_enable_device(dp) < 0) { dev_err(&dp->dev, "Cannot enable PCI device\n"); goto err_out; } if ((dp->resource[0].flags & IORESOURCE_MEM) == 0) goto err_disable; addr = pci_resource_start(dp, 0); size = pci_resource_len(dp, 0); if (addr == 0) goto err_disable; p = framebuffer_alloc(0, &dp->dev); if (p == NULL) { dev_err(&dp->dev, "Cannot allocate framebuffer structure\n"); rc = -ENOMEM; goto err_disable; } if (pci_request_region(dp, 0, "chipsfb") != 0) { dev_err(&dp->dev, "Cannot request framebuffer\n"); rc = -EBUSY; goto err_release_fb; } #ifdef __BIG_ENDIAN addr += 0x800000; #endif pci_read_config_word(dp, PCI_COMMAND, &cmd); cmd |= 3; pci_write_config_word(dp, PCI_COMMAND, cmd); #ifdef CONFIG_PMAC_BACKLIGHT mutex_lock(&pmac_backlight_mutex); if (pmac_backlight) { pmac_backlight->props.power = FB_BLANK_UNBLANK; backlight_update_status(pmac_backlight); } mutex_unlock(&pmac_backlight_mutex); #endif #ifdef CONFIG_PPC p->screen_base = __ioremap(addr, 0x200000, _PAGE_NO_CACHE); #else p->screen_base = ioremap(addr, 0x200000); #endif if (p->screen_base == NULL) { dev_err(&dp->dev, "Cannot map framebuffer\n"); rc = -ENOMEM; goto err_release_pci; } pci_set_drvdata(dp, p); init_chips(p, addr); if (register_framebuffer(p) < 0) { dev_err(&dp->dev,"C&T 65550 framebuffer failed to register\n"); goto err_unmap; } dev_info(&dp->dev,"fb%d: Chips 65550 frame buffer" " (%dK RAM detected)\n", p->node, p->fix.smem_len / 1024); return 0; err_unmap: iounmap(p->screen_base); err_release_pci: pci_release_region(dp, 0); err_release_fb: framebuffer_release(p); err_disable: err_out: return rc; }
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; }
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; } 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 __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) { /* */ while (in_be16(fb_regs+0x4800) & 1) ; out_be16(fb_regs+0x4800, 0); /* */ out_be16(fb_regs+0x4510, 0); /* */ out_be16(fb_regs+0x4512, 0); /* */ out_be16(fb_regs+0x4514, 0); /* */ out_be16(fb_regs+0x4516, 0); /* */ out_be16(fb_regs+0x4206, 0x90); /* */ out_be16(fb_regs+0x60a2, 0); /* */ out_be16(fb_regs+0x60bc, 0); /* */ } /* */ 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); /* */ 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); /* */ 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); /* */ topcat_blit(0, 0, 0, 0, fb_width, fb_height, RR_CLEAR); /* */ 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 bw2_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; struct bw2_par *par; int linebytes, err; info = framebuffer_alloc(sizeof(struct bw2_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); info->fix.smem_start = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; sbusfb_fill_var(&info->var, dp, 1); linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->var.red.length = info->var.green.length = info->var.blue.length = info->var.bits_per_pixel; info->var.red.offset = info->var.green.offset = info->var.blue.offset = 0; par->regs = of_ioremap(&op->resource[0], BWTWO_REGISTER_OFFSET, sizeof(struct bw2_regs), "bw2 regs"); if (!par->regs) goto out_release_fb; if (!of_find_property(dp, "width", NULL)) { err = bw2_do_default_mode(par, info, &linebytes); if (err) goto out_unmap_regs; } info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); info->flags = FBINFO_DEFAULT; info->fbops = &bw2_ops; info->screen_base = of_ioremap(&op->resource[0], 0, info->fix.smem_len, "bw2 ram"); if (!info->screen_base) { err = -ENOMEM; goto out_unmap_regs; } bw2_blank(FB_BLANK_UNBLANK, info); bw2_init_fix(info, linebytes); err = register_framebuffer(info); if (err < 0) goto out_unmap_screen; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: bwtwo at %lx:%lx\n", dp->full_name, par->which_io, info->fix.smem_start); return 0; out_unmap_screen: of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len); out_unmap_regs: of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs)); out_release_fb: framebuffer_release(info); out_err: return err; }
static void __init offb_init_fb(const char *name, const char *full_name, int width, int height, int depth, int pitch, unsigned long address, struct device_node *dp) { unsigned long res_size = pitch * height * depth / 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; int size; 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 != 16 && depth != 32) { printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth); release_mem_region(res_start, res_size); return; } size = sizeof(struct fb_info) + sizeof(u32) * 17; info = kmalloc(size, GFP_ATOMIC); if (info == 0) { release_mem_region(res_start, res_size); return; } memset(info, 0, size); fix = &info->fix; var = &info->var; 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) { /* XXX kludge for ati */ if (dp && !strncmp(name, "ATY,Rage128", 11)) { unsigned long regbase = dp->addrs[2].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_r128; } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) || !strncmp(name, "ATY,RageM3p12A", 14))) { unsigned long regbase = dp->parent->addrs[2].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_M3A; } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { unsigned long regbase = dp->parent->addrs[2].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_M3B; } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { unsigned long regbase = dp->addrs[1].address; par->cmap_adr = ioremap(regbase, 0x1FFF); par->cmap_type = cmap_radeon; } else if (!strncmp(name, "ATY,", 4)) { unsigned long base = address & 0xff000000UL; par->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0; par->cmap_data = par->cmap_adr + 1; par->cmap_type = cmap_m64; } else if (device_is_compatible(dp, "pci1014,b7")) { unsigned long regbase = dp->addrs[0].address; par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); par->cmap_type = cmap_gxt2000; } fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR; } else fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR : */ FB_VISUAL_TRUECOLOR; var->xoffset = var->yoffset = 0; var->bits_per_pixel = depth; 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 16: /* 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 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; info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); info->par = par; info->pseudo_palette = (void *) (info + 1); info->flags = FBINFO_DEFAULT; fb_alloc_cmap(&info->cmap, 256, 0); if (register_framebuffer(info) < 0) { kfree(info); release_mem_region(res_start, res_size); return; } printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", info->node, full_name); }
static int __devinit hecubafb_probe(struct platform_device *dev) { struct fb_info *info; struct hecuba_board *board; int retval = -ENOMEM; int videomemorysize; unsigned char *videomemory; struct hecubafb_par *par; board = dev->dev.platform_data; if (!board) return -EINVAL; if (!try_module_get(board->owner)) return -ENODEV; videomemorysize = (DPY_W*DPY_H)/8; videomemory = vzalloc(videomemorysize); if (!videomemory) goto err_videomem_alloc; info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev); if (!info) goto err_fballoc; info->screen_base = (char __force __iomem *)videomemory; info->fbops = &hecubafb_ops; info->var = hecubafb_var; info->fix = hecubafb_fix; info->fix.smem_len = videomemorysize; par = info->par; par->info = info; par->board = board; par->send_command = apollo_send_command; par->send_data = apollo_send_data; info->flags = FBINFO_FLAG_DEFAULT | FBINFO_VIRTFB; info->fbdefio = &hecubafb_defio; fb_deferred_io_init(info); retval = register_framebuffer(info); if (retval < 0) goto err_fbreg; platform_set_drvdata(dev, info); printk(KERN_INFO "fb%d: Hecuba frame buffer device, using %dK of video memory\n", info->node, videomemorysize >> 10); retval = par->board->init(par); if (retval < 0) goto err_fbreg; return 0; err_fbreg: framebuffer_release(info); err_fballoc: vfree(videomemory); err_videomem_alloc: module_put(board->owner); return retval; }
__s32 Fb_Init(__u32 from) { __s32 i; __bool need_open_hdmi = 0; __disp_fb_create_para_t fb_para = { .primary_screen_id = 0, }; __inf("Fb_Init:%d\n", from); if (from == 0) { /* call from lcd driver */ #ifdef CONFIG_FB_SUNXI_RESERVED_MEM __inf("fbmem: fb_start=%lu, fb_size=%lu\n", fb_start, fb_size); disp_create_heap((unsigned long)(__va(fb_start)), fb_size); #endif for (i = 0; i < SUNXI_MAX_FB; i++) { g_fbi.fbinfo[i] = framebuffer_alloc(0, g_fbi.dev); g_fbi.fbinfo[i]->fbops = &dispfb_ops; g_fbi.fbinfo[i]->flags = 0; g_fbi.fbinfo[i]->device = g_fbi.dev; g_fbi.fbinfo[i]->par = &g_fbi; g_fbi.fbinfo[i]->var.xoffset = 0; g_fbi.fbinfo[i]->var.yoffset = 0; g_fbi.fbinfo[i]->var.xres = 800; g_fbi.fbinfo[i]->var.yres = 480; g_fbi.fbinfo[i]->var.xres_virtual = 800; g_fbi.fbinfo[i]->var.yres_virtual = 480 * 2; g_fbi.fbinfo[i]->var.nonstd = 0; g_fbi.fbinfo[i]->var.grayscale = 0; g_fbi.fbinfo[i]->var.bits_per_pixel = 32; g_fbi.fbinfo[i]->var.transp.length = 8; g_fbi.fbinfo[i]->var.red.length = 8; g_fbi.fbinfo[i]->var.green.length = 8; g_fbi.fbinfo[i]->var.blue.length = 8; g_fbi.fbinfo[i]->var.transp.offset = 24; g_fbi.fbinfo[i]->var.red.offset = 16; g_fbi.fbinfo[i]->var.green.offset = 8; g_fbi.fbinfo[i]->var.blue.offset = 0; g_fbi.fbinfo[i]->var.activate = FB_ACTIVATE_FORCE; g_fbi.fbinfo[i]->fix.type = FB_TYPE_PACKED_PIXELS; g_fbi.fbinfo[i]->fix.type_aux = 0; g_fbi.fbinfo[i]->fix.visual = FB_VISUAL_TRUECOLOR; g_fbi.fbinfo[i]->fix.xpanstep = 1; g_fbi.fbinfo[i]->fix.ypanstep = 1; g_fbi.fbinfo[i]->fix.ywrapstep = 0; g_fbi.fbinfo[i]->fix.accel = FB_ACCEL_NONE; g_fbi.fbinfo[i]->fix.line_length = g_fbi.fbinfo[i]->var.xres_virtual * 4; g_fbi.fbinfo[i]->fix.smem_len = g_fbi.fbinfo[i]->fix.line_length * g_fbi.fbinfo[i]->var.yres_virtual * 2; g_fbi.fbinfo[i]->screen_base = NULL; g_fbi.fbinfo[i]->pseudo_palette = g_fbi.pseudo_palette[i]; g_fbi.fbinfo[i]->fix.smem_start = 0x0; g_fbi.fbinfo[i]->fix.mmio_start = 0; g_fbi.fbinfo[i]->fix.mmio_len = 0; if (fb_alloc_cmap(&g_fbi.fbinfo[i]->cmap, 256, 1) < 0) return -ENOMEM; } parser_disp_init_para(&(g_fbi.disp_init)); } if (g_fbi.disp_init.b_init) { __u32 sel = 0; for (sel = 0; sel < 2; sel++) { if (((sel == 0) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1)) || ((sel == 1) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0))) { if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_HDMI) need_open_hdmi = 1; } } } if (need_open_hdmi == 1 && from == 0) /* it is called from lcd driver, but hdmi need to be opened */ return 0; else if (need_open_hdmi == 0 && from == 1) /* it is called from hdmi driver, but hdmi need not be opened */ return 0; if (g_fbi.disp_init.b_init) { __u32 fb_num = 0, sel = 0; for (sel = 0; sel < 2; sel++) { if (((sel == 0) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1)) || ((sel == 1) && (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0))) { if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_LCD) { DRV_lcd_open(sel); } else if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_TV) { BSP_disp_tv_set_mode(sel, g_fbi.disp_init. tv_mode[sel]); BSP_disp_tv_open(sel); } else if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_HDMI) { BSP_disp_hdmi_set_mode(sel, g_fbi.disp_init. tv_mode[sel]); BSP_disp_hdmi_open(sel); } else if (g_fbi.disp_init.output_type[sel] == DISP_OUTPUT_TYPE_VGA) { BSP_disp_vga_set_mode(sel, g_fbi.disp_init. vga_mode[sel]); BSP_disp_vga_open(sel); } } } fb_num = (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN) ? 2 : 1; for (i = 0; i < fb_num; i++) { __u32 screen_id = i; disp_fb_to_var(g_fbi.disp_init.format[i], g_fbi.disp_init.seq[i], g_fbi.disp_init.br_swap[i], &(g_fbi.fbinfo[i]->var)); if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) screen_id = 1; fb_para.buffer_num = g_fbi.disp_init.buffer_num[i]; fb_para.width = BSP_disp_get_screen_width(screen_id); fb_para.height = BSP_disp_get_screen_height(screen_id); fb_para.output_width = BSP_disp_get_screen_width(screen_id); fb_para.output_height = BSP_disp_get_screen_height(screen_id); fb_para.mode = (g_fbi.disp_init.scaler_mode[i] == 0) ? DISP_LAYER_WORK_MODE_NORMAL : DISP_LAYER_WORK_MODE_SCALER; if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN0) { fb_para.fb_mode = FB_MODE_SCREEN0; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_SCREEN1) { fb_para.fb_mode = FB_MODE_SCREEN1; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN) { if (i == 0) fb_para.fb_mode = FB_MODE_SCREEN0; else fb_para.fb_mode = FB_MODE_SCREEN1; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_SAME_SCREEN) { fb_para.fb_mode = FB_MODE_DUAL_SAME_SCREEN_TB; fb_para.height *= 2; fb_para.output_height *= 2; } else if (g_fbi.disp_init.disp_mode == DISP_INIT_MODE_TWO_DIFF_SCREEN_SAME_CONTENTS) { fb_para.fb_mode = FB_MODE_DUAL_DIFF_SCREEN_SAME_CONTENTS; fb_para.output_width = BSP_disp_get_screen_width(fb_para. primary_screen_id); fb_para.output_height = BSP_disp_get_screen_height(fb_para. primary_screen_id); fb_para.aux_output_width = BSP_disp_get_screen_width(1 - fb_para. primary_screen_id); fb_para.aux_output_height = BSP_disp_get_screen_height(1 - fb_para. primary_screen_id); } Display_Fb_Request(i, &fb_para); #if 0 fb_draw_colorbar((__u32)g_fbi.fbinfo[i]->screen_base, fb_para.width, fb_para.height * fb_para.buffer_num, &(g_fbi.fbinfo[i]->var)); #endif } for (i = 0; i < SUNXI_MAX_FB; i++) /* Register framebuffers after they are initialized */ register_framebuffer(g_fbi.fbinfo[i]); if (g_fbi.disp_init.scaler_mode[0]) BSP_disp_print_reg(0, DISP_REG_SCALER0); if (g_fbi.disp_init.scaler_mode[1]) BSP_disp_print_reg(0, DISP_REG_SCALER1); if (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN1) { BSP_disp_print_reg(0, DISP_REG_IMAGE0); BSP_disp_print_reg(0, DISP_REG_LCDC0); if ((g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[0] == DISP_OUTPUT_TYPE_VGA)) BSP_disp_print_reg(0, DISP_REG_TVEC0); } if (g_fbi.disp_init.disp_mode != DISP_INIT_MODE_SCREEN0) { BSP_disp_print_reg(0, DISP_REG_IMAGE1); BSP_disp_print_reg(0, DISP_REG_LCDC1); if ((g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_TV) || (g_fbi.disp_init.output_type[1] == DISP_OUTPUT_TYPE_VGA)) BSP_disp_print_reg(0, DISP_REG_TVEC1); } BSP_disp_print_reg(0, DISP_REG_CCMU); BSP_disp_print_reg(0, DISP_REG_PWM); BSP_disp_print_reg(0, DISP_REG_PIOC); } __inf("Fb_Init: END\n"); return 0; } EXPORT_SYMBOL(Fb_Init); __s32 Fb_Exit(void) { __u8 fb_id = 0; for (fb_id = 0; fb_id < SUNXI_MAX_FB; fb_id++) { if (g_fbi.fbinfo[fb_id] == NULL) continue; Display_Fb_Release(fb_id); unregister_framebuffer(g_fbi.fbinfo[fb_id]); framebuffer_release(g_fbi.fbinfo[fb_id]); g_fbi.fbinfo[fb_id] = NULL; } return 0; }
static int __devinit tcx_init_one(struct of_device *op) { struct device_node *dp = op->node; struct all_info *all; int linebytes, i, err; all = kzalloc(sizeof(*all), GFP_KERNEL); if (!all) return -ENOMEM; spin_lock_init(&all->par.lock); all->par.lowdepth = (of_find_property(dp, "tcx-8-bit", NULL) != NULL); sbusfb_fill_var(&all->info.var, dp->node, 8); all->info.var.red.length = 8; all->info.var.green.length = 8; all->info.var.blue.length = 8; linebytes = of_getintprop_default(dp, "linebytes", all->info.var.xres); all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres); all->par.tec = of_ioremap(&op->resource[7], 0, sizeof(struct tcx_tec), "tcx tec"); all->par.thc = of_ioremap(&op->resource[9], 0, sizeof(struct tcx_thc), "tcx thc"); all->par.bt = of_ioremap(&op->resource[8], 0, sizeof(struct bt_regs), "tcx dac"); all->info.screen_base = of_ioremap(&op->resource[0], 0, all->par.fbsize, "tcx ram"); if (!all->par.tec || !all->par.thc || !all->par.bt || !all->info.screen_base) { tcx_unmap_regs(all); kfree(all); return -ENOMEM; } memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map)); if (!all->par.lowdepth) { all->par.cplane = of_ioremap(&op->resource[4], 0, all->par.fbsize * sizeof(u32), "tcx cplane"); if (!all->par.cplane) { tcx_unmap_regs(all); kfree(all); return -ENOMEM; } } else { all->par.mmap_map[1].size = SBUS_MMAP_EMPTY; all->par.mmap_map[4].size = SBUS_MMAP_EMPTY; all->par.mmap_map[5].size = SBUS_MMAP_EMPTY; all->par.mmap_map[6].size = SBUS_MMAP_EMPTY; } all->par.physbase = 0; all->par.which_io = op->resource[0].flags & IORESOURCE_BITS; for (i = 0; i < TCX_MMAP_ENTRIES; i++) { int j; switch (i) { case 10: j = 12; break; case 11: case 12: j = i - 1; break; default: j = i; break; }; all->par.mmap_map[i].poff = op->resource[j].start; } all->info.flags = FBINFO_DEFAULT; all->info.fbops = &tcx_ops; all->info.par = &all->par; /* Initialize brooktree DAC. */ sbus_writel(0x04 << 24, &all->par.bt->addr); /* color planes */ sbus_writel(0xff << 24, &all->par.bt->control); sbus_writel(0x05 << 24, &all->par.bt->addr); sbus_writel(0x00 << 24, &all->par.bt->control); sbus_writel(0x06 << 24, &all->par.bt->addr); /* overlay plane */ sbus_writel(0x73 << 24, &all->par.bt->control); sbus_writel(0x07 << 24, &all->par.bt->addr); sbus_writel(0x00 << 24, &all->par.bt->control); tcx_reset(&all->info); tcx_blank(FB_BLANK_UNBLANK, &all->info); if (fb_alloc_cmap(&all->info.cmap, 256, 0)) { tcx_unmap_regs(all); kfree(all); return -ENOMEM; } fb_set_cmap(&all->info.cmap, &all->info); tcx_init_fix(&all->info, linebytes); err = register_framebuffer(&all->info); if (err < 0) { fb_dealloc_cmap(&all->info.cmap); tcx_unmap_regs(all); kfree(all); return err; } dev_set_drvdata(&op->dev, all); printk("%s: TCX at %lx:%lx, %s\n", dp->full_name, all->par.which_io, op->resource[0].start, all->par.lowdepth ? "8-bit only" : "24-bit depth"); return 0; }
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: 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: 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: 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; info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); info->pseudo_palette = (void *) (info + 1); info->flags = FBINFO_DEFAULT | foreign_endian; fb_alloc_cmap(&info->cmap, 256, 0); if (register_framebuffer(info) < 0) { iounmap(par->cmap_adr); par->cmap_adr = NULL; iounmap(info->screen_base); framebuffer_release(info); release_mem_region(res_start, res_size); return; } printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", info->node, full_name); }
static int __devinit nuc900fb_probe(struct platform_device *pdev) { struct nuc900fb_info *fbi; struct nuc900fb_display *display; struct fb_info *fbinfo; struct nuc900fb_mach_info *mach_info; struct resource *res; int ret; int irq; int i; int size; dev_dbg(&pdev->dev, "devinit\n"); mach_info = pdev->dev.platform_data; if (mach_info == NULL) { dev_err(&pdev->dev, "no platform data for lcd, cannot attach\n"); return -EINVAL; } if (mach_info->default_display > mach_info->num_displays) { dev_err(&pdev->dev, "default display No. is %d but only %d displays \n", mach_info->default_display, mach_info->num_displays); return -EINVAL; } display = mach_info->displays + mach_info->default_display; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq for device\n"); return -ENOENT; } fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev); if (!fbinfo) return -ENOMEM; platform_set_drvdata(pdev, fbinfo); fbi = fbinfo->par; fbi->dev = &pdev->dev; #ifdef CONFIG_CPU_NUC950 fbi->drv_type = LCDDRV_NUC950; #endif res = platform_get_resource(pdev, IORESOURCE_MEM, 0); size = (res->end - res->start) + 1; fbi->mem = request_mem_region(res->start, size, pdev->name); if (fbi->mem == NULL) { dev_err(&pdev->dev, "failed to alloc memory region\n"); ret = -ENOENT; goto free_fb; } fbi->io = ioremap(res->start, size); if (fbi->io == NULL) { dev_err(&pdev->dev, "ioremap() of lcd registers failed\n"); ret = -ENXIO; goto release_mem_region; } fbi->irq_base = fbi->io + REG_LCM_INT_CS; /* Stop the LCD */ writel(0, fbi->io + REG_LCM_DCCS); /* fill the fbinfo*/ strcpy(fbinfo->fix.id, driver_name); fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; fbinfo->fix.type_aux = 0; fbinfo->fix.xpanstep = 0; fbinfo->fix.ypanstep = 0; fbinfo->fix.ywrapstep = 0; fbinfo->fix.accel = FB_ACCEL_NONE; fbinfo->var.nonstd = 0; fbinfo->var.activate = FB_ACTIVATE_NOW; fbinfo->var.accel_flags = 0; fbinfo->var.vmode = FB_VMODE_NONINTERLACED; fbinfo->fbops = &nuc900fb_ops; fbinfo->flags = FBINFO_FLAG_DEFAULT; fbinfo->pseudo_palette = &fbi->pseudo_pal; ret = request_irq(irq, nuc900fb_irqhandler, 0, pdev->name, fbinfo); if (ret) { dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n", irq, ret); ret = -EBUSY; goto release_regs; } fbi->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(fbi->clk)) { printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n"); ret = PTR_ERR(fbi->clk); goto release_irq; } clk_enable(fbi->clk); dev_dbg(&pdev->dev, "got and enabled clock\n"); fbi->clk_rate = clk_get_rate(fbi->clk); /* calutate the video buffer size */ for (i = 0; i < mach_info->num_displays; i++) { unsigned long smem_len = mach_info->displays[i].xres; smem_len *= mach_info->displays[i].yres; smem_len *= mach_info->displays[i].bpp; smem_len >>= 3; if (fbinfo->fix.smem_len < smem_len) fbinfo->fix.smem_len = smem_len; } /* Initialize Video Memory */ ret = nuc900fb_map_video_memory(fbinfo); if (ret) { printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret); goto release_clock; } dev_dbg(&pdev->dev, "got video memory\n"); fbinfo->var.xres = display->xres; fbinfo->var.yres = display->yres; fbinfo->var.bits_per_pixel = display->bpp; nuc900fb_init_registers(fbinfo); nuc900fb_check_var(&fbinfo->var, fbinfo); ret = nuc900fb_cpufreq_register(fbi); if (ret < 0) { dev_err(&pdev->dev, "Failed to register cpufreq\n"); goto free_video_memory; } ret = register_framebuffer(fbinfo); if (ret) { printk(KERN_ERR "failed to register framebuffer device: %d\n", ret); goto free_cpufreq; } printk(KERN_INFO "fb%d: %s frame buffer device\n", fbinfo->node, fbinfo->fix.id); return 0; free_cpufreq: nuc900fb_cpufreq_deregister(fbi); free_video_memory: nuc900fb_unmap_video_memory(fbinfo); release_clock: clk_disable(fbi->clk); clk_put(fbi->clk); release_irq: free_irq(irq, fbi); release_regs: iounmap(fbi->io); release_mem_region: release_mem_region(res->start, size); free_fb: framebuffer_release(fbinfo); return ret; }
static int qtft_fb_probe(struct platform_device * dev) { struct fb_info *info; int retval = -ENOMEM; func_in(); // 分配显存 if (!(videomemory = rvmalloc(videomemorysize))) return retval; memset(videomemory, 0, videomemorysize); // 动态分配 fb_info info = framebuffer_alloc((sizeof(u32)*16), &dev->dev); if (!info) goto err0; // 虚拟地址 info->screen_base = (char __iomem *)videomemory; info->screen_size = videomemorysize; // 文件操作符 qtft_fb_ops 在 ops.c 中定义 info->fbops = &qtft_fb_ops; info->var = qtft_fb_var_default; qtft_fb_fix_default.smem_start = (unsigned long) videomemory; qtft_fb_fix_default.smem_len = videomemorysize; info->fix = qtft_fb_fix_default; // 16色伪调色板指针指向了 info->par 的私有空间 info->pseudo_palette = info->par; info->par = NULL; info->flags = FBINFO_DEFAULT; // 为16色伪调色板分配内存 retval = fb_alloc_cmap(&info->cmap, 16, 0); if (retval < 0) goto err1; retval = register_framebuffer(info); if (retval < 0) goto err2; // 初始化 LCD 模块 retval = lcd_init(); if (retval < 0) goto err3; retval = lcd_hard_reset(); if (retval < 0) goto err3; retval = lcd_normal_config(); if (retval < 0) goto err3; lcd_address_set(0,0,(info->var).xres,(info->var).yres); // 将 info 指针存入平台设备私有数据 platform_set_drvdata(dev, info); printk(KERN_INFO "SPI QVGA TFT LCD driver: fb%d, %ldK video memory\n", info->node, videomemorysize >> 10); goto out; err3: unregister_framebuffer(info); err2: fb_dealloc_cmap(&info->cmap); err1: framebuffer_release(info); err0: rvfree(videomemory, videomemorysize); out: func_out(); return retval; }
static int __init sh_mobile_lcdc_probe(struct platform_device *pdev) { struct fb_info *info; struct sh_mobile_lcdc_priv *priv; struct sh_mobile_lcdc_info *pdata; struct sh_mobile_lcdc_chan_cfg *cfg; struct resource *res; int error; void *buf; int i, j; if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data defined\n"); error = -EINVAL; goto err0; } 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"); error = -ENOENT; goto err0; } priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "cannot allocate device data\n"); error = -ENOMEM; goto err0; } 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; priv->dev = &pdev->dev; platform_set_drvdata(pdev, priv); pdata = pdev->dev.platform_data; j = 0; for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) { priv->ch[j].lcdc = priv; memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i])); error = sh_mobile_lcdc_check_interface(&priv->ch[i]); if (error) { dev_err(&pdev->dev, "unsupported interface type\n"); goto err1; } init_waitqueue_head(&priv->ch[i].frame_end_wait); priv->ch[j].pan_offset = 0; priv->ch[j].new_pan_offset = 0; switch (pdata->ch[i].chan) { case LCDC_CHAN_MAINLCD: priv->ch[j].enabled = 1 << 1; priv->ch[j].reg_offs = lcdc_offs_mainlcd; j++; break; case LCDC_CHAN_SUBLCD: priv->ch[j].enabled = 1 << 2; priv->ch[j].reg_offs = lcdc_offs_sublcd; j++; break; } } if (!j) { dev_err(&pdev->dev, "no channels defined\n"); error = -EINVAL; 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->base = ioremap_nocache(res->start, (res->end - res->start) + 1); for (i = 0; i < j; i++) { cfg = &priv->ch[i].cfg; priv->ch[i].info = framebuffer_alloc(0, &pdev->dev); if (!priv->ch[i].info) { dev_err(&pdev->dev, "unable to allocate fb_info\n"); error = -ENOMEM; break; } info = priv->ch[i].info; info->fbops = &sh_mobile_lcdc_ops; info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres; info->var.yres = cfg->lcd_cfg.yres; info->var.yres_virtual = info->var.yres * 2; info->var.width = cfg->lcd_size_cfg.width; info->var.height = cfg->lcd_size_cfg.height; info->var.activate = FB_ACTIVATE_NOW; error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp); if (error) break; info->fix = sh_mobile_lcdc_fix; info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8); info->fix.smem_len = info->fix.line_length * info->var.yres_virtual; buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len, &priv->ch[i].dma_handle, GFP_KERNEL); if (!buf) { dev_err(&pdev->dev, "unable to allocate buffer\n"); error = -ENOMEM; break; } info->pseudo_palette = &priv->ch[i].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, priv->ch[i].dma_handle); break; } memset(buf, 0, info->fix.smem_len); info->fix.smem_start = priv->ch[i].dma_handle; info->screen_base = buf; info->device = &pdev->dev; info->par = &priv->ch[i]; } 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) { priv->ch->sglist = vmalloc(sizeof(struct scatterlist) * info->fix.smem_len >> PAGE_SHIFT); if (!priv->ch->sglist) { dev_err(&pdev->dev, "cannot allocate sglist\n"); goto err1; } } 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", (int) ch->cfg.lcd_cfg.xres, (int) ch->cfg.lcd_cfg.yres, ch->cfg.bpp); if (info->fbdefio) sh_mobile_lcdc_clk_off(priv); }
static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->dev.of_node; struct fb_info *info; struct cg14_par *par; int is_8mb, linebytes, i, err; info = framebuffer_alloc(sizeof(struct cg14_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); if (!strcmp(dp->parent->name, "sbus") || !strcmp(dp->parent->name, "sbi")) { info->fix.smem_start = op->resource[0].start; par->iospace = op->resource[0].flags & IORESOURCE_BITS; } else { info->fix.smem_start = op->resource[1].start; par->iospace = op->resource[0].flags & IORESOURCE_BITS; } par->regs = of_ioremap(&op->resource[0], 0, sizeof(struct cg14_regs), "cg14 regs"); par->clut = of_ioremap(&op->resource[0], CG14_CLUT1, sizeof(struct cg14_clut), "cg14 clut"); par->cursor = of_ioremap(&op->resource[0], CG14_CURSORREGS, sizeof(struct cg14_cursor), "cg14 cursor"); info->screen_base = of_ioremap(&op->resource[1], 0, info->fix.smem_len, "cg14 ram"); if (!par->regs || !par->clut || !par->cursor || !info->screen_base) goto out_unmap_regs; is_8mb = (((op->resource[1].end - op->resource[1].start) + 1) == (8 * 1024 * 1024)); BUILD_BUG_ON(sizeof(par->mmap_map) != sizeof(__cg14_mmap_map)); memcpy(&par->mmap_map, &__cg14_mmap_map, sizeof(par->mmap_map)); for (i = 0; i < CG14_MMAP_ENTRIES; i++) { struct sbus_mmap_map *map = &par->mmap_map[i]; if (!map->size) break; if (map->poff & 0x80000000) map->poff = (map->poff & 0x7fffffff) + (op->resource[0].start - op->resource[1].start); if (is_8mb && map->size >= 0x100000 && map->size <= 0x400000) map->size *= 2; } par->mode = MDI_8_PIX; par->ramsize = (is_8mb ? 0x800000 : 0x400000); info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; info->fbops = &cg14_ops; __cg14_reset(par); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; fb_set_cmap(&info->cmap, info); cg14_init_fix(info, linebytes, dp); err = register_framebuffer(info); if (err < 0) goto out_dealloc_cmap; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: cgfourteen at %lx:%lx, %dMB\n", dp->full_name, par->iospace, info->fix.smem_start, par->ramsize >> 20); return 0; out_dealloc_cmap: fb_dealloc_cmap(&info->cmap); out_unmap_regs: cg14_unmap_regs(op, info, par); out_err: return err; }
/* * Initialisation */ static int __init sun3fb_init_fb(int fbtype, unsigned long addr) { static struct sbus_dev sdb; struct fb_fix_screeninfo *fix; struct fb_var_screeninfo *var; struct display *disp; struct fb_info_sbusfb *fb; struct fbtype *type; int linebytes, w, h, depth; char *p = NULL; fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC); if (!fb) return -ENOMEM; memset(fb, 0, sizeof(struct fb_info_sbusfb)); fix = &fb->fix; var = &fb->var; disp = &fb->disp; type = &fb->type; sdb.reg_addrs[0].phys_addr = addr; fb->sbdp = &sdb; type->fb_type = fbtype; type->fb_height = h = 900; type->fb_width = w = 1152; sizechange: type->fb_depth = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8; linebytes = w * depth / 8; type->fb_size = PAGE_ALIGN((linebytes) * h); /* fb->x_margin = (w & 7) / 2; fb->y_margin = (h & 15) / 2; */ fb->x_margin = fb->y_margin = 0; var->xres_virtual = w; var->yres_virtual = h; var->xres = w - 2*fb->x_margin; var->yres = h - 2*fb->y_margin; var->bits_per_pixel = depth; var->height = var->width = -1; var->pixclock = 10000; var->vmode = FB_VMODE_NONINTERLACED; var->red.length = var->green.length = var->blue.length = 8; fix->line_length = linebytes; fix->smem_len = type->fb_size; fix->type = FB_TYPE_PACKED_PIXELS; fix->visual = FB_VISUAL_PSEUDOCOLOR; fb->info.fbops = &sun3fb_ops; fb->info.disp = disp; fb->info.currcon = -1; strcpy(fb->info.fontname, fontname); fb->info.changevar = NULL; fb->info.switch_con = &sun3fbcon_switch; fb->info.updatevar = &sun3fbcon_updatevar; fb->info.flags = FBINFO_FLAG_DEFAULT; fb->cursor.hwsize.fbx = 32; fb->cursor.hwsize.fby = 32; if (depth > 1 && !fb->color_map) { if((fb->color_map = kmalloc(256 * 3, GFP_ATOMIC))==NULL) return -ENOMEM; } switch(fbtype) { #ifdef CONFIG_FB_CGSIX case FBTYPE_SUNFAST_COLOR: p = cgsixfb_init(fb); break; #endif #ifdef CONFIG_FB_BWTWO case FBTYPE_SUN2BW: p = bwtwofb_init(fb); break; #endif #ifdef CONFIG_FB_CGTHREE case FBTYPE_SUN4COLOR: case FBTYPE_SUN3COLOR: type->fb_size = 0x100000; p = cgthreefb_init(fb); break; #endif } fix->smem_start = (unsigned long)fb->info.screen_base; // FIXME if (!p) { kfree(fb); return -ENODEV; } if (p == SBUSFBINIT_SIZECHANGE) goto sizechange; disp->dispsw = &fb->dispsw; if (fb->setcursor) { fb->dispsw.cursor = sun3fb_cursor; if (curblink) { fb->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE; init_timer(&fb->cursor.timer); fb->cursor.timer.expires = jiffies + fb->cursor.blink_rate; fb->cursor.timer.data = (unsigned long)fb; fb->cursor.timer.function = sun3fb_cursor_timer_handler; add_timer(&fb->cursor.timer); } } fb->cursor.mode = CURSOR_SHAPE; fb->dispsw.set_font = sun3fb_set_font; fb->setup = fb->dispsw.setup; fb->dispsw.setup = sun3fb_disp_setup; fb->dispsw.clear_margins = NULL; disp->var = *var; disp->visual = fix->visual; disp->type = fix->type; disp->type_aux = fix->type_aux; disp->line_length = fix->line_length; if (fb->blank) disp->can_soft_blank = 1; sun3fb_set_var(var, -1, &fb->info); if (register_framebuffer(&fb->info) < 0) { kfree(fb); return -EINVAL; } printk("fb%d: %s\n", fb->info.node, p); return 0; }
int atmel_lcdc_register(struct device_d *dev, struct atmel_lcdfb_devdata *data) { struct atmel_lcdfb_info *sinfo; struct atmel_lcdfb_platform_data *pdata = dev->platform_data; int ret = 0; struct fb_info *info; if (!pdata) { dev_err(dev, "missing platform_data\n"); return -EINVAL; } sinfo = xzalloc(sizeof(*sinfo)); sinfo->pdata = pdata; sinfo->mmio = dev_request_mem_region(dev, 0); sinfo->dev_data = data; /* just init */ info = &sinfo->info; info->priv = sinfo; info->fbops = &atmel_lcdc_ops; info->modes.modes = pdata->mode_list; info->modes.num_modes = pdata->num_modes; info->mode = &info->modes.modes[0]; info->xres = info->mode->xres; info->yres = info->mode->yres; info->bits_per_pixel = pdata->default_bpp; /* Enable LCDC Clocks */ sinfo->bus_clk = clk_get(dev, "hck1"); if (IS_ERR(sinfo->bus_clk)) { ret = PTR_ERR(sinfo->bus_clk); goto err; } sinfo->lcdc_clk = clk_get(dev, "lcdc_clk"); if (IS_ERR(sinfo->lcdc_clk)) { ret = PTR_ERR(sinfo->lcdc_clk); goto put_bus_clk; } atmel_lcdfb_start_clock(sinfo); if (data->dma_desc_size) sinfo->dma_desc = dma_alloc_coherent(data->dma_desc_size); ret = register_framebuffer(info); if (ret != 0) { dev_err(dev, "Failed to register framebuffer\n"); goto stop_clk; } return ret; stop_clk: if (sinfo->dma_desc) free(sinfo->dma_desc); atmel_lcdfb_stop_clock(sinfo); clk_put(sinfo->lcdc_clk); put_bus_clk: clk_put(sinfo->bus_clk); err: return ret; }
int init_zion_vga(void) { int ret; zion_params_t *params = find_zion(0); u32 off_addr; if(params == NULL){ return -ENODEV; } PINFO("ZION VGA Frame Buffer Driver Installed.\n"); PDEBUG("compiled "__DATE__" "__TIME__"\n"); //Check Fireball if((params->revision & 0xF000) == 0xF000){ PINFO("This is fireball! ZION VGA cannot be used!!\n"); return 0; } #ifdef CONFIG_ZION_FB_SETUP PINFO("Setting FB Address ... %p and %p\n", (void *)CONFIG_ZION_FB_FIRST_ADDR, (void *)CONFIG_ZION_FB_SECOND_ADDR); mbus_writel(CONFIG_ZION_FB_FIRST_ADDR, MBUS_ADDR(params,ZIONVGA_BUFFER_BASE_ADDRESS_0)); mbus_writel(CONFIG_ZION_FB_SECOND_ADDR, MBUS_ADDR(params,ZIONVGA_BUFFER_BASE_ADDRESS_1)); #endif //CONFIG_ZION_FB_SETUP //Get VGA FB Region off_addr = mbus_readl(MBUS_ADDR(params, ZIONVGA_BUFFER_BASE_ADDRESS_0)); dma_direction[0] = params->whole_sdram_addr + off_addr; PINFO("FB1_BUS_ADDR:%p\n",(void *)dma_direction[0]); off_addr = mbus_readl(MBUS_ADDR(params, ZIONVGA_BUFFER_BASE_ADDRESS_1)); dma_direction[1] = params->whole_sdram_addr + off_addr; PINFO("FB2_BUS_ADDR:%p\n",(void *)dma_direction[1]); memset(&zion_fb_info, 0, sizeof(struct zion_vga_info)); zion_fb_info.ram_address = (unsigned long)__get_free_pages(GFP_KERNEL | __GFP_DMA, ZIONVGA_VRAM_ORDER); if(!zion_fb_info.ram_address){ PERROR("failed get_free_pages(): ram_address\n"); ret = -ENOMEM; goto fail_gfp_fb; } memset((void *)zion_fb_info.ram_address, 0, ZIONVGA_VRAM_SIZE); PDEBUG("ram_address = 0x%08lx (virtual)\n", (unsigned long)zion_fb_info.ram_address); PDEBUG("ram_address = 0x%08lx (physical)\n", virt_to_bus((void *)zion_fb_info.ram_address)); zion_fb_info.fb_info.screen_base = (void __iomem *)zion_fb_info.ram_address; zion_fb_info.fb_info.fbops = &zion_vga_ops; //setup var_screen_info zionvga_encode_var(&default_var); zion_fb_info.fb_info.var = default_var; zionvga_encode_fix(&zion_fb_info.fb_info.fix); zion_fb_info.fb_info.par = &zion_current_par; // This should give a reasonable default video mode ret = fb_alloc_cmap(&zion_fb_info.fb_info.cmap, 256, 0); if(ret){ PERROR( "failed fb_alloc_cmap()\n" ); ret = -ENOMEM; goto fail_alloc_cmap; } if(register_framebuffer(&zion_fb_info.fb_info) < 0){ PERROR("failed register_framebuffer()\n"); ret = -EINVAL; goto fail_reg_fb; } PINFO("fb%d: %s frame buffer device\n", zion_fb_info.fb_info.node, zion_fb_info.fb_info.fix.id); return 0; fail_reg_fb: fb_dealloc_cmap( &zion_fb_info.fb_info.cmap); fail_alloc_cmap: free_pages(zion_fb_info.ram_address, ZIONVGA_VRAM_ORDER); fail_gfp_fb: return ret; }
static int s5pv210_lcd_init(void) { struct clk *s5pv210_clk; s5pv210_lcd = framebuffer_alloc(0, NULL); strcpy(s5pv210_lcd->fix.id, "s5pv210_lcd"); s5pv210_lcd->fix.smem_len = 800*480*4; s5pv210_lcd->fix.type = FB_TYPE_PACKED_PIXELS; s5pv210_lcd->fix.visual = FB_VISUAL_TRUECOLOR; s5pv210_lcd->fix.line_length = 800*4; s5pv210_lcd->var.xres = 800; s5pv210_lcd->var.yres = 480; s5pv210_lcd->var.xres_virtual = 800; s5pv210_lcd->var.yres_virtual = 480; s5pv210_lcd->var.bits_per_pixel = 32; s5pv210_lcd->var.red.offset = 16; s5pv210_lcd->var.red.length = 8; s5pv210_lcd->var.green.offset = 8; s5pv210_lcd->var.green.length = 8; s5pv210_lcd->var.blue.offset = 0; s5pv210_lcd->var.blue.length = 8; s5pv210_lcd->var.activate = FB_ACTIVATE_NOW; s5pv210_lcd->fbops = &s5pv210_lcdfb_ops; s5pv210_lcd->screen_size = 800*480*4; gpf0con = ioremap(0xE0200120,4); gpf1con = ioremap(0xE0200140,4); gpf2con = ioremap(0xE0200160,4); gpf3con = ioremap(0xE0200180,4); //gpd0con = ioremap(0xE02000A0,4); //gpd0dat = ioremap(0xE02000A4,4); *gpf0con = 0x22222222; // GPF0[7:0] *gpf1con = 0x22222222; // GPF1[7:0] *gpf2con = 0x22222222; // GPF2[7:0] *gpf3con = 0x22222222; // GPF3[7:0] //*gpd0con |= 1<<4; //*gpd0dat |= 1<<1; s5pv210_clk = clk_get(NULL, "lcd"); if (!s5pv210_clk || IS_ERR(s5pv210_clk)) { printk(KERN_INFO "failed to get lcd clock source\n"); } clk_enable(s5pv210_clk); //display_control = ioremap(0xe0107008,4); vidcon0 = ioremap(0xF8000000,4); vidcon1 = ioremap(0xF8000004,4); wincon0 = ioremap(0xF8000020,4); vidosd0a = ioremap(0xF8000040,4); vidosd0b = ioremap(0xF8000044,4); vidosd0c = ioremap(0xF8000048,4); vidw00add0b0 = ioremap(0xF80000A0,4); vidw00add1b0 = ioremap(0xF80000D0,4); vidw00add2 = ioremap(0xF8000100,4); vidtcon0 = ioremap(0xF8000010,4); vidtcon1 = ioremap(0xF8000014,4); vidtcon2 = ioremap(0xF8000018,4); wpalcon = ioremap(0xF80001A0,4); shadowcon = ioremap(0xF8000034,4); //*display_control = 2<<0; //Page 1222 *vidcon0 &= ~((3<<26) | (1<<18) | (0xff<<6) | (1<<2)); /* RGB I/F, RGB Parallel format, */ *vidcon0 |= ((4<<6) | (1<<4) ); /* Divided by CLKVAL_F,vclk== HCLK / (CLKVAL+1) = 166.75/5 = 33.35MHz */ //1211 *vidcon1 &= ~(1<<7); *vidcon1 |= ((1<<6) | (1<<5)); *vidtcon0 = (VBPD << 16) | (VFPD << 8) | (VSPW << 0); *vidtcon1 = (HBPD << 16) | (HFPD << 8) | (HSPW << 0); *vidtcon2 = (LINEVAL << 11) | (HOZVAL << 0); *wincon0 &= ~(0xf << 2); *wincon0 |= (0xB<<2)/*|(1<<15)*/; *vidosd0a = (LeftTopX<<11) | (LeftTopY << 0); *vidosd0b = (RightBotX<<11) | (RightBotY << 0); *vidosd0c = (LINEVAL + 1) * (HOZVAL + 1); s5pv210_lcd->screen_base = dma_alloc_writecombine(NULL, s5pv210_lcd->fix.smem_len, (dma_addr_t *)&s5pv210_lcd->fix.smem_start, GFP_KERNEL); *vidw00add0b0 = s5pv210_lcd->fix.smem_start; *vidw00add1b0 = s5pv210_lcd->fix.smem_start + s5pv210_lcd->fix.smem_len; *shadowcon = 0x1; *vidcon0 |= 0x3; *wincon0 |= 1; register_framebuffer(s5pv210_lcd); return 0; }
static int initialise_dpsv_fbi(void) { int fbram_offset; int ret = 0; struct fb_fix_screeninfo* fix = &dpsv_fbi.fix; struct fb_var_screeninfo* var = &dpsv_fbi.var; if (!mdi.fbi_p1 || !mdi.fbi_p2) { DPSV_ERR ("Invalid State of DPSV\n"); //panic("Invalid State of DPSV"); return -1; } snprintf(fix->id, sizeof(fix->id), "msmfb40_dpsv"); //TBD calculate fix.smem_length //Copy fix and var params from P1's, by default. //TBD: later, just do memcopy instead of elementary copy. fix->type = mdi.fbi_p1->fix.type; fix->xpanstep = mdi.fbi_p1->fix.xpanstep; fix->ypanstep = mdi.fbi_p1->fix.ypanstep; fix->line_length = mdi.fbi_p1->fix.line_length; var->vmode = mdi.fbi_p1->var.vmode; var->blue.offset = mdi.fbi_p1->var.blue.offset; var->green.offset = mdi.fbi_p1->var.green.offset; var->red.offset = mdi.fbi_p1->var.red.offset; var->blue.length = mdi.fbi_p1->var.blue.length; var->green.length = mdi.fbi_p1->var.green.length; var->red.length = mdi.fbi_p1->var.red.length; var->blue.msb_right = mdi.fbi_p1->var.blue.msb_right; var->green.msb_right = mdi.fbi_p1->var.green.msb_right; var->red.msb_right = mdi.fbi_p1->var.red.msb_right; var->transp.offset = mdi.fbi_p1->var.transp.offset; var->transp.length = mdi.fbi_p1->var.transp.length; var->pixclock = mdi.fbi_p1->var.pixclock; var->xres = mdi.fbi_p1->var.xres; //xres is greater of the two, which is in P1. var->yres = mdi.fbi_p1->var.yres + mdi.fbi_p2->var.yres; var->xres_virtual = var->xres; var->yres_virtual = mdi.fbi_p1->var.yres_virtual + mdi.fbi_p2->var.yres_virtual; var->yres_virtual *= 2; /******** TEMP ONLY, to allow GRALLOC to function *********/ var->bits_per_pixel = mdi.fbi_p1->var.bits_per_pixel; fix->smem_len = fix->line_length * var->yres_virtual; dpsv_fbi.fbops = &msm_fb_dpsv_ops; dpsv_fbi.flags = FBINFO_FLAG_DEFAULT; dpsv_fbi.pseudo_palette = mdi.fbi_p1->pseudo_palette; dpsv_fbi.par = NULL; //no parameter currently needed for DPSV. fix->type_aux = 0; /* if type == FB_TYPE_INTERLEAVED_PLANES */ fix->visual = FB_VISUAL_TRUECOLOR; /* True Color */ fix->ywrapstep = 0; /* No support */ fix->mmio_start = 0; /* No MMIO Address */ fix->mmio_len = 0; /* No MMIO Address */ fix->accel = FB_ACCEL_NONE;/* FB_ACCEL_MSM needes to be added in fb.h */ var->xoffset = 0, /* Offset from virtual to visible */ var->yoffset = 0, /* resolution */ var->grayscale = 0, /* No graylevels */ var->nonstd = 0, /* standard pixel format */ var->activate = FB_ACTIVATE_VBL, /* activate it at vsync */ var->height = -1, /* height of picture in mm */ var->width = -1, /* width of picture in mm */ var->accel_flags = 0, /* acceleration flags */ var->sync = 0, /* see FB_SYNC_* */ var->rotate = 0, /* angle we rotate counter clockwise */ fbram_offset = PAGE_ALIGN((int)fbram)-(int)fbram; fbram += fbram_offset; fbram_phys += fbram_offset; fbram_size -= fbram_offset; if (fbram_size < fix->smem_len) { DPSV_ERR ("error: no more framebuffer memory!\n"); return -ENOMEM; } dpsv_fbi.screen_base = fbram; dpsv_fbi.fix.smem_start = (unsigned long)fbram_phys; mdi.fbi_p1->screen_base = fbram; mdi.fbi_p1->fix.smem_start = (unsigned long)fbram_phys; mdi.fbi_p2->screen_base = fbram + mdi.fbi_p1->fix.line_length * mdi.fbi_p1->var.yres; mdi.fbi_p2->fix.smem_start = (unsigned long)fbram_phys + mdi.fbi_p1->fix.line_length * mdi.fbi_p1->var.yres; //Set yres_virtual of both panels'f fb_info, according to pysically stitched DPSV buffer design. mdi.fbi_p1->var.yres_virtual = ( mdi.fbi_p1->var.yres ) * 2 + mdi.fbi_p2->var.yres; //sumeet TBD: 2 is for fb_page; generalise it. mdi.fbi_p2->var.yres_virtual = mdi.fbi_p1->var.yres + ( mdi.fbi_p2->var.yres * 2 ); //fixup xres_virtual, line_length and smem_len of panel2. mdi.fbi_p2->var.xres_virtual = mdi.fbi_p1->var.xres ; mdi.fbi_p2->var.bits_per_pixel = mdi.fbi_p1->var.bits_per_pixel; mdi.fbi_p2->fix.line_length = mdi.fbi_p2->var.xres_virtual * mdi.fbi_p2->var.bits_per_pixel/8; mdi.fbi_p2->fix.smem_len = fix->line_length * mdi.fbi_p2->var.yres_virtual; DPSV_DBG ("FrameBuffer[DPSV.P1] %dx%d size=%d bytes screen_base = %#X\n", mdi.fbi_p1->var.xres, mdi.fbi_p1->var.yres, mdi.fbi_p1->fix.smem_len, (unsigned int)mdi.fbi_p1->screen_base); DPSV_DBG ("FrameBuffer[DPSV.P2] %dx%d size=%d bytes screen_base = %#X\n", mdi.fbi_p2->var.xres, mdi.fbi_p2->var.yres, mdi.fbi_p2->fix.smem_len, (unsigned int)mdi.fbi_p2->screen_base); memset(dpsv_fbi.screen_base, 0x0, fix->smem_len); ret = register_framebuffer (&dpsv_fbi); if (ret < 0) { printk("ERROR registering DPSV framebuffer: %d\n", ret); return ret; } DPSV_DBG ("FrameBuffer[DPSV] %dx%d size=%d bytes is registered successfully!\n", dpsv_fbi.var.xres, dpsv_fbi.var.yres, dpsv_fbi.fix.smem_len); #ifdef SLIDE ret = input_register_handler(&sld_input_handler); DPSV_DBG("input_register_handler: %d.\n", ret ); #endif fbram += fix->smem_len; fbram_phys += fix->smem_len; fbram_size -= fix->smem_len; return ret; };
/** * 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; }
struct fb_info* einkfb_probe(struct platform_device *dev) { einkfb_init_err_t err = einkfb_init_err_none; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; struct fb_info *info = NULL; boot_milestone_write(EINK_HAL_STARTED_BOM, EINK_HAL_STARTED_BOM_SZ); if ( !(info = framebuffer_alloc(sizeof(struct fb_info), &dev->dev)) ) goto err1; // einkfb_init_err_framebuffer_alloc einkfb_fbinfo = info; info->fbops = &einkfb_ops; /* * Get the module's variable & fixed screeninfo. */ if ( EINKFB_FAILURE == HAL_SW_INIT(&var, &fix) ) goto err2; // einkfb_init_err_hw_sw_init /* * Allocate an address space for our real, virtual, and scratch buffers. */ einkfb_blen = BPP_SIZE((var.xres * (var.yres + 1)), var.bits_per_pixel); einkfb_size = BPP_SIZE((var.xres * var.yres), var.bits_per_pixel); einkfb_mem = FB_ROUNDUP(einkfb_blen, PAGE_SIZE) * 3; einkfb_dma = HAL_NEEDS_DMA(); if ( !(einkfb = EINKFB_MALLOC_HAL(einkfb_mem, einkfb_dma ? &einkfb_phys : NULL)) ) goto err3; // einkfb_init_err_einkfb_malloc_hal /* * Clear memory to prevent kernel info from "leaking" * into userspace. */ einkfb_memset(einkfb, einkfb_white(var.bits_per_pixel), einkfb_mem); fix.smem_start = einkfb_dma ? (unsigned long)einkfb_phys.addr : (unsigned long)einkfb; fix.smem_len = (einkfb_mem/3) << 1; /* real & virtual */ info->screen_base = (char __iomem *)einkfb; info->screen_size = einkfb_mem/3; /* just real */ info->var = var; info->fix = fix; info->pseudo_palette = NULL; /* info->par */ info->par = NULL; info->flags = FBINFO_FLAG_DEFAULT; if ( fb_alloc_cmap(&info->cmap, BPP_MAX(var.bits_per_pixel), 0) < 0 ) goto err4; // einkfb_init_err_fb_alloc_cmap switch ( var.bits_per_pixel ) { case EINKFB_1BPP: fb_copy_cmap(&einkfb_1bpp_cmap, &info->cmap); break; case EINKFB_2BPP: fb_copy_cmap(&einkfb_2bpp_cmap, &info->cmap); break; case EINKFB_4BPP: fb_copy_cmap(&einkfb_4bpp_cmap, &info->cmap); break; case EINKFB_8BPP: fb_copy_cmap(&einkfb_8bpp_cmap, &info->cmap); break; } einkfb_bpp = info->var.bits_per_pixel; einkfb_xres = info->var.xres; einkfb_yres = info->var.yres; einkfb_vfb = einkfb + info->screen_size; einkfb_buf = einkfb_vfb + info->screen_size; einkfb_hw_bringup_mode_actual = HAL_HW_INIT(info, einkfb_hw_bringup_mode); einkfb_align_x = einkfb_set_byte_alignment_x(einkfb_bpp); einkfb_align_y = einkfb_set_byte_alignment_y(einkfb_bpp); if ( register_framebuffer(info) < 0 ) goto err5; // einkfb_init_err_register_framebuffer BLANK_INIT(); boot_milestone_write(EINK_HAL_LOADED_BOM, EINK_HAL_LOADED_BOM_SZ); return info; err5: err++; // err = einkfb_init_err_register_framebuffer err4: err++; // err = einkfb_init_err_fb_alloc_cmap err3: err++; // err = einkfb_init_err_einkfb_malloc_hal err2: err++; // err = einkfb_init_err_hw_sw_init err1: err++; // err = einkfb_init_err_fb_info_alloc einkfb_remove(info, err); return NULL; }
static struct device_t * fb_f1c500s_probe(struct driver_t * drv, struct dtnode_t * n) { struct fb_f1c500s_pdata_t * pdat; struct framebuffer_t * fb; struct device_t * dev; char * clkdefe = dt_read_string(n, "clock-name-defe", NULL); char * clkdebe = dt_read_string(n, "clock-name-debe", NULL); char * clktcon = dt_read_string(n, "clock-name-tcon", NULL); int i; if(!search_clk(clkdefe) || !search_clk(clkdebe) || !search_clk(clktcon)) return NULL; pdat = malloc(sizeof(struct fb_f1c500s_pdata_t)); if(!pdat) return NULL; fb = malloc(sizeof(struct framebuffer_t)); if(!fb) { free(pdat); return NULL; } pdat->virtdefe = phys_to_virt(F1C500S_DEFE_BASE); pdat->virtdebe = phys_to_virt(F1C500S_DEBE_BASE); pdat->virttcon = phys_to_virt(F1C500S_TCON_BASE); pdat->virtgpio = phys_to_virt(F1C500S_GPIO_BASE); pdat->clkdefe = strdup(clkdefe); pdat->clkdebe = strdup(clkdebe); pdat->clktcon = strdup(clktcon); pdat->rstdefe = dt_read_int(n, "reset-defe", -1); pdat->rstdebe = dt_read_int(n, "reset-debe", -1); pdat->rsttcon = dt_read_int(n, "reset-tcon", -1); pdat->width = dt_read_int(n, "width", 320); pdat->height = dt_read_int(n, "height", 240); pdat->pwidth = dt_read_int(n, "physical-width", 216); pdat->pheight = dt_read_int(n, "physical-height", 135); pdat->bits_per_pixel = dt_read_int(n, "bits-per-pixel", 18); pdat->bytes_per_pixel = dt_read_int(n, "bytes-per-pixel", 4); pdat->index = 0; pdat->vram[0] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->vram[1] = dma_alloc_noncoherent(pdat->width * pdat->height * pdat->bytes_per_pixel); pdat->nrl = region_list_alloc(0); pdat->orl = region_list_alloc(0); pdat->timing.pixel_clock_hz = dt_read_long(n, "clock-frequency", 8000000); pdat->timing.h_front_porch = dt_read_int(n, "hfront-porch", 40); pdat->timing.h_back_porch = dt_read_int(n, "hback-porch", 87); pdat->timing.h_sync_len = dt_read_int(n, "hsync-len", 1); pdat->timing.v_front_porch = dt_read_int(n, "vfront-porch", 13); pdat->timing.v_back_porch = dt_read_int(n, "vback-porch", 31); pdat->timing.v_sync_len = dt_read_int(n, "vsync-len", 1); pdat->timing.h_sync_active = dt_read_bool(n, "hsync-active", 0); pdat->timing.v_sync_active = dt_read_bool(n, "vsync-active", 0); pdat->timing.den_active = dt_read_bool(n, "den-active", 0); pdat->timing.clk_active = dt_read_bool(n, "clk-active", 0); pdat->backlight = search_led(dt_read_string(n, "backlight", NULL)); fb->name = alloc_device_name(dt_read_name(n), dt_read_id(n)); fb->width = pdat->width; fb->height = pdat->height; fb->pwidth = pdat->pwidth; fb->pheight = pdat->pheight; fb->bytes = pdat->bytes_per_pixel; fb->setbl = fb_setbl; fb->getbl = fb_getbl; fb->create = fb_create; fb->destroy = fb_destroy; fb->present = fb_present; fb->priv = pdat; clk_enable(pdat->clkdefe); clk_enable(pdat->clkdebe); clk_enable(pdat->clktcon); if(pdat->rstdefe >= 0) reset_deassert(pdat->rstdefe); if(pdat->rstdebe >= 0) reset_deassert(pdat->rstdebe); if(pdat->rsttcon >= 0) reset_deassert(pdat->rsttcon); for(i = 0x0800; i < 0x1000; i += 4) write32(pdat->virtdebe + i, 0); fb_f1c500s_init(pdat); if(!register_framebuffer(&dev, fb)) { clk_disable(pdat->clkdefe); clk_disable(pdat->clkdebe); clk_disable(pdat->clktcon); free(pdat->clkdefe); free(pdat->clkdebe); free(pdat->clktcon); dma_free_noncoherent(pdat->vram[0]); dma_free_noncoherent(pdat->vram[1]); region_list_free(pdat->nrl); region_list_free(pdat->orl); free_device_name(fb->name); free(fb->priv); free(fb); return NULL; } dev->driver = drv; return dev; }
static int wm8505fb_probe(struct platform_device *pdev) { struct wm8505fb_info *fbi; struct resource *res; struct display_timings *disp_timing; void *addr; int ret; struct fb_videomode mode; u32 bpp; dma_addr_t fb_mem_phys; unsigned long fb_mem_len; void *fb_mem_virt; fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) + sizeof(u32) * 16, GFP_KERNEL); if (!fbi) { dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); return -ENOMEM; } strcpy(fbi->fb.fix.id, DRIVER_NAME); fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; fbi->fb.fix.xpanstep = 1; fbi->fb.fix.ypanstep = 1; fbi->fb.fix.ywrapstep = 0; fbi->fb.fix.accel = FB_ACCEL_NONE; fbi->fb.fbops = &wm8505fb_ops; fbi->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN | FBINFO_VIRTFB | FBINFO_PARTIAL_PAN_OK; fbi->fb.node = -1; addr = fbi; addr = addr + sizeof(struct wm8505fb_info); fbi->fb.pseudo_palette = addr; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); fbi->regbase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(fbi->regbase)) return PTR_ERR(fbi->regbase); disp_timing = of_get_display_timings(pdev->dev.of_node); if (!disp_timing) return -EINVAL; ret = of_get_fb_videomode(pdev->dev.of_node, &mode, OF_USE_NATIVE_MODE); if (ret) return ret; ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp); if (ret) return ret; fb_videomode_to_var(&fbi->fb.var, &mode); fbi->fb.var.nonstd = 0; fbi->fb.var.activate = FB_ACTIVATE_NOW; fbi->fb.var.height = -1; fbi->fb.var.width = -1; /* try allocating the framebuffer */ fb_mem_len = mode.xres * mode.yres * 2 * (bpp / 8); fb_mem_virt = dmam_alloc_coherent(&pdev->dev, fb_mem_len, &fb_mem_phys, GFP_KERNEL); if (!fb_mem_virt) { pr_err("%s: Failed to allocate framebuffer\n", __func__); return -ENOMEM; } fbi->fb.var.xres_virtual = mode.xres; fbi->fb.var.yres_virtual = mode.yres * 2; fbi->fb.var.bits_per_pixel = bpp; fbi->fb.fix.smem_start = fb_mem_phys; fbi->fb.fix.smem_len = fb_mem_len; fbi->fb.screen_base = fb_mem_virt; fbi->fb.screen_size = fb_mem_len; fbi->contrast = 0x10; ret = wm8505fb_set_par(&fbi->fb); if (ret) { dev_err(&pdev->dev, "Failed to set parameters\n"); return ret; } if (fb_alloc_cmap(&fbi->fb.cmap, 256, 0) < 0) { dev_err(&pdev->dev, "Failed to allocate color map\n"); return -ENOMEM; } wm8505fb_init_hw(&fbi->fb); platform_set_drvdata(pdev, fbi); ret = register_framebuffer(&fbi->fb); if (ret < 0) { dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n", ret); if (fbi->fb.cmap.len) fb_dealloc_cmap(&fbi->fb.cmap); return ret; } ret = device_create_file(&pdev->dev, &dev_attr_contrast); if (ret < 0) { printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", fbi->fb.node, ret); } printk(KERN_INFO "fb%d: %s frame buffer at 0x%lx-0x%lx\n", fbi->fb.node, fbi->fb.fix.id, fbi->fb.fix.smem_start, fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1); return 0; }
static int hvfb_probe(struct hv_device *hdev, const struct hv_vmbus_device_id *dev_id) { struct fb_info *info; struct hvfb_par *par; int ret; info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device); if (!info) { pr_err("No memory for framebuffer info\n"); return -ENOMEM; } par = info->par; par->info = info; par->fb_ready = false; init_completion(&par->wait); INIT_DELAYED_WORK(&par->dwork, hvfb_update_work); /* Connect to VSP */ hv_set_drvdata(hdev, info); ret = synthvid_connect_vsp(hdev); if (ret) { pr_err("Unable to connect to VSP\n"); goto error1; } ret = hvfb_getmem(info); if (ret) { pr_err("No memory for framebuffer\n"); goto error2; } hvfb_get_option(info); pr_info("Screen resolution: %dx%d, Color depth: %d\n", screen_width, screen_height, screen_depth); /* Set up fb_info */ info->flags = FBINFO_DEFAULT; info->var.xres_virtual = info->var.xres = screen_width; info->var.yres_virtual = info->var.yres = screen_height; info->var.bits_per_pixel = screen_depth; if (info->var.bits_per_pixel == 16) { info->var.red = (struct fb_bitfield){11, 5, 0}; info->var.green = (struct fb_bitfield){5, 6, 0}; info->var.blue = (struct fb_bitfield){0, 5, 0}; info->var.transp = (struct fb_bitfield){0, 0, 0}; } else { info->var.red = (struct fb_bitfield){16, 8, 0}; info->var.green = (struct fb_bitfield){8, 8, 0}; info->var.blue = (struct fb_bitfield){0, 8, 0}; info->var.transp = (struct fb_bitfield){24, 8, 0}; } info->var.activate = FB_ACTIVATE_NOW; info->var.height = -1; info->var.width = -1; info->var.vmode = FB_VMODE_NONINTERLACED; strcpy(info->fix.id, KBUILD_MODNAME); info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = FB_VISUAL_TRUECOLOR; info->fix.line_length = screen_width * screen_depth / 8; info->fix.accel = FB_ACCEL_NONE; info->fbops = &hvfb_ops; info->pseudo_palette = par->pseudo_palette; /* Send config to host */ ret = synthvid_send_config(hdev); if (ret) goto error; ret = register_framebuffer(info); if (ret) { pr_err("Unable to register framebuffer\n"); goto error; } par->fb_ready = true; par->synchronous_fb = false; par->hvfb_panic_nb.notifier_call = hvfb_on_panic; atomic_notifier_chain_register(&panic_notifier_list, &par->hvfb_panic_nb); return 0; error: hvfb_putmem(info); error2: vmbus_close(hdev->channel); error1: cancel_delayed_work_sync(&par->dwork); hv_set_drvdata(hdev, NULL); framebuffer_release(info); return ret; } static int hvfb_remove(struct hv_device *hdev) { struct fb_info *info = hv_get_drvdata(hdev); struct hvfb_par *par = info->par; atomic_notifier_chain_unregister(&panic_notifier_list, &par->hvfb_panic_nb); par->update = false; par->fb_ready = false; unregister_framebuffer(info); cancel_delayed_work_sync(&par->dwork); vmbus_close(hdev->channel); hv_set_drvdata(hdev, NULL); hvfb_putmem(info); framebuffer_release(info); return 0; } static const struct pci_device_id pci_stub_id_table[] = { { .vendor = PCI_VENDOR_ID_MICROSOFT, .device = PCI_DEVICE_ID_HYPERV_VIDEO, }, { /* end of list */ } }; static const struct hv_vmbus_device_id id_table[] = { /* Synthetic Video Device GUID */ {HV_SYNTHVID_GUID}, {} }; MODULE_DEVICE_TABLE(pci, pci_stub_id_table); MODULE_DEVICE_TABLE(vmbus, id_table); static struct hv_driver hvfb_drv = { .name = KBUILD_MODNAME, .id_table = id_table, .probe = hvfb_probe, .remove = hvfb_remove, }; static int hvfb_pci_stub_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { return 0; } static void hvfb_pci_stub_remove(struct pci_dev *pdev) { } static struct pci_driver hvfb_pci_stub_driver = { .name = KBUILD_MODNAME, .id_table = pci_stub_id_table, .probe = hvfb_pci_stub_probe, .remove = hvfb_pci_stub_remove, }; static int __init hvfb_drv_init(void) { int ret; ret = vmbus_driver_register(&hvfb_drv); if (ret != 0) return ret; ret = pci_register_driver(&hvfb_pci_stub_driver); if (ret != 0) { vmbus_driver_unregister(&hvfb_drv); return ret; } return 0; } static void __exit hvfb_drv_exit(void) { pci_unregister_driver(&hvfb_pci_stub_driver); vmbus_driver_unregister(&hvfb_drv); } module_init(hvfb_drv_init); module_exit(hvfb_drv_exit); MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver");
static int sprdfb_probe(struct platform_device *pdev) { struct fb_info *fb = NULL; struct sprdfb_device *dev = NULL; int ret = 0; #ifdef CONFIG_OF struct resource r; #ifdef CONFIG_FB_LOW_RES_SIMU uint32_t display_size_array[2]; #endif pr_debug(KERN_INFO "sprdfb: [%s]\n", __FUNCTION__); #else pr_debug(KERN_INFO "sprdfb: [%s], id = %d\n", __FUNCTION__, pdev->id); #endif fb = framebuffer_alloc(sizeof(struct sprdfb_device), &pdev->dev); if (!fb) { printk(KERN_ERR "sprdfb: sprdfb_probe allocate buffer fail.\n"); ret = -ENOMEM; goto err0; } dev = fb->par; dev->fb = fb; #ifdef CONFIG_OF dev->of_dev = &(pdev->dev); dev->dev_id = of_alias_get_id(pdev->dev.of_node, "lcd"); printk("sprdfb: [%s] id = %d\n", __FUNCTION__, dev->dev_id); #else dev->dev_id = pdev->id; #endif if((SPRDFB_MAINLCD_ID != dev->dev_id) &&(SPRDFB_SUBLCD_ID != dev->dev_id)){ printk(KERN_ERR "sprdfb: sprdfb_probe fail. (unsupported device id)\n"); goto err0; } switch(SPRDFB_IN_DATA_TYPE){ case SPRD_IN_DATA_TYPE_ABGR888: dev->bpp = 32; break; case SPRD_IN_DATA_TYPE_BGR565: dev->bpp = 16; break; default: dev->bpp = 32; break; } if(SPRDFB_MAINLCD_ID == dev->dev_id){ dev->ctrl = &sprdfb_dispc_ctrl; #ifdef CONFIG_OF if(0 != of_address_to_resource(pdev->dev.of_node, 0, &r)){ printk(KERN_ERR "sprdfb: sprdfb_probe fail. (can't get register base address)\n"); goto err0; } g_dispc_base_addr = (unsigned long)ioremap_nocache(r.start, resource_size(&r)); if(!g_dispc_base_addr) BUG(); printk("sprdfb: set g_dispc_base_addr = %ld\n", g_dispc_base_addr); #endif } dev->frame_count = 0; dev->logo_buffer_addr_v = 0; dev->capability = sprdfb_config_capability(); if(sprdfb_panel_get(dev)){ dev->panel_ready = true; #ifdef CONFIG_OF #ifdef CONFIG_FB_LOW_RES_SIMU ret = of_property_read_u32_array(pdev->dev.of_node, "sprd,fb_display_size", display_size_array, 2); if (0 != ret) { printk("sprdfb: read display_size from dts fail (%d)\n", ret); dev->display_width = dev->panel->width; dev->display_height = dev->panel->height; } else { dev->display_width = display_size_array[0]; dev->display_height = display_size_array[1]; } #endif #endif dev->ctrl->logo_proc(dev); }else{ dev->panel_ready = false; } dev->ctrl->early_init(dev); if(!dev->panel_ready){ if (!sprdfb_panel_probe(dev)) { ret = -EIO; goto cleanup; } } ret = setup_fb_mem(dev, pdev); if (ret) { goto cleanup; } setup_fb_info(dev); /* register framebuffer device */ ret = register_framebuffer(fb); if (ret) { printk(KERN_ERR "sprdfb: sprdfb_probe register framebuffer fail.\n"); goto cleanup; } platform_set_drvdata(pdev, dev); sprdfb_create_sysfs(dev); dev->ctrl->init(dev); #ifdef CONFIG_HAS_EARLYSUSPEND dev->early_suspend.suspend = sprdfb_early_suspend; dev->early_suspend.resume = sprdfb_late_resume; dev->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; register_early_suspend(&dev->early_suspend); #endif #ifdef CONFIG_FB_ESD_SUPPORT pr_debug("sprdfb: Init ESD work queue!\n"); INIT_DELAYED_WORK(&dev->ESD_work, ESD_work_func); // sema_init(&dev->ESD_lock, 1); if(SPRDFB_PANEL_IF_DPI == dev->panel_if_type){ dev->ESD_timeout_val = SPRDFB_ESD_TIME_OUT_VIDEO; }else{ dev->ESD_timeout_val = SPRDFB_ESD_TIME_OUT_CMD; } dev->ESD_work_start = false; dev->check_esd_time = 0; dev->reset_dsi_time = 0; dev->panel_reset_time = 0; #endif return 0; cleanup: sprdfb_panel_remove(dev); dev->ctrl->uninit(dev); fb_free_resources(dev); err0: dev_err(&pdev->dev, "failed to probe sprdfb\n"); return ret; }
static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; struct fb_info *info; struct leo_par *par; int linebytes, err; info = framebuffer_alloc(sizeof(struct leo_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); par->physbase = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; sbusfb_fill_var(&info->var, dp->node, 32); leo_fixup_var_rgb(&info->var); linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); par->lc_ss0_usr = of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR, 0x1000, "leolc ss0usr"); par->ld_ss0 = of_ioremap(&op->resource[0], LEO_OFF_LD_SS0, 0x1000, "leold ss0"); par->ld_ss1 = of_ioremap(&op->resource[0], LEO_OFF_LD_SS1, 0x1000, "leold ss1"); par->lx_krn = of_ioremap(&op->resource[0], LEO_OFF_LX_KRN, 0x1000, "leolx krn"); par->cursor = of_ioremap(&op->resource[0], LEO_OFF_LX_CURSOR, sizeof(struct leo_cursor), "leolx cursor"); info->screen_base = of_ioremap(&op->resource[0], LEO_OFF_SS0, 0x800000, "leo ram"); if (!par->lc_ss0_usr || !par->ld_ss0 || !par->ld_ss1 || !par->lx_krn || !par->cursor || !info->screen_base) goto out_unmap_regs; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; info->fbops = &leo_ops; leo_init_wids(info); leo_init_hw(info); leo_blank(0, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; leo_init_fix(info, dp); err = register_framebuffer(info); if (err < 0) goto out_dealloc_cmap; dev_set_drvdata(&op->dev, info); printk("%s: leo at %lx:%lx\n", dp->full_name, par->which_io, par->physbase); return 0; out_dealloc_cmap: fb_dealloc_cmap(&info->cmap); out_unmap_regs: leo_unmap_regs(op, info, par); framebuffer_release(info); out_err: return err; }
static int __init vfb_probe(struct platform_device *dev) { struct fb_info *info; int retval = -ENOMEM; /* Reserve the framebuffer memory */ if (!request_mem_region(vfb_addr, vfb_size, "STM32F4 Framebuffer")) { printk(KERN_ERR "vfb: unable to reserve " "framebuffer at 0x%0x\n", (unsigned int)vfb_addr); retval = -EBUSY; goto fail_reqmem; } /* Allocate framebuffer info structure */ info = framebuffer_alloc(sizeof(struct fb_info), &dev->dev); if (!info) { printk(KERN_ERR "vfb: unable to reserve framebuffer info\n"); retval = -ENOMEM; goto fail_fballoc; } /* For real video cards we use ioremap */ info->screen_base = ioremap(vfb_addr, vfb_size); if (!info->screen_base) { printk(KERN_ERR "vfb: unable to map framebuffer\n"); retval = -ENOMEM; goto fail_remap; } /* Assign the frame buffer data */ info->screen_size = vfb_size; info->fbops = &vfb_ops; /* * VFB must clear memory to prevent kernel info * leakage into userspace * VGA-based drivers MUST NOT clear memory if * they want to be able to take over vgacon */ memset(info->screen_base, 0, info->screen_size); retval = fb_find_mode(&info->var, info, NULL, NULL, 0, NULL, 8); if ((!retval) || (retval == 4)) memcpy(&(info->var), &vfb_default, sizeof(struct fb_var_screeninfo)); vfb_fix.smem_start = vfb_addr; vfb_fix.smem_len = vfb_size; memcpy(&(info->fix), &vfb_fix, sizeof(struct fb_fix_screeninfo)); /* Allocate pseudo palette data */ info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL); if (!info->pseudo_palette) { printk(KERN_ERR "vfb: unable to reserve palette memory\n"); retval = -ENOMEM; goto fail_palette; } //info->pseudo_palette = info->par; info->par = NULL; info->flags = FBINFO_FLAG_DEFAULT; /* * We expect the boot loader to have initialized the chip * with appropriate parameters from which we can determinte * the flavor of lcd panel attached */ retval = init_vals(info); if (retval < 0) { printk(KERN_ERR "vfb: unable to reserve cmap memory\n"); goto fail_cmap; } /* Regiser the framebuffer */ retval = register_framebuffer(info); if (retval < 0) { printk(KERN_ERR "vfb: unable to register framebuffer\n"); goto fail_register; } /* Assign the driver data */ platform_set_drvdata(dev, info); /* Everything is OK */ printk(KERN_INFO "fb%d: Virtual frame buffer device, " "using %ldK of video memory\n", info->node, info->screen_size >> 10); return 0; /* There is an error! */ fail_register: fb_dealloc_cmap(&info->cmap); fail_cmap: kfree(info->pseudo_palette); fail_palette: iounmap(info->screen_base); fail_remap: framebuffer_release(info); fail_fballoc: release_mem_region(vfb_addr, vfb_size); fail_reqmem: return retval; }
static int tcx_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; struct fb_info *info; struct tcx_par *par; int linebytes, i, err; info = framebuffer_alloc(sizeof(struct tcx_par), &op->dev); err = -ENOMEM; if (!info) goto out_err; par = info->par; spin_lock_init(&par->lock); par->lowdepth = (of_find_property(dp, "tcx-8-bit", NULL) != NULL); sbusfb_fill_var(&info->var, dp, 8); info->var.red.length = 8; info->var.green.length = 8; info->var.blue.length = 8; linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres); par->tec = of_ioremap(&op->resource[7], 0, sizeof(struct tcx_tec), "tcx tec"); par->thc = of_ioremap(&op->resource[9], 0, sizeof(struct tcx_thc), "tcx thc"); par->bt = of_ioremap(&op->resource[8], 0, sizeof(struct bt_regs), "tcx dac"); info->screen_base = of_ioremap(&op->resource[0], 0, info->fix.smem_len, "tcx ram"); if (!par->tec || !par->thc || !par->bt || !info->screen_base) goto out_unmap_regs; memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map)); if (!par->lowdepth) { par->cplane = of_ioremap(&op->resource[4], 0, info->fix.smem_len * sizeof(u32), "tcx cplane"); if (!par->cplane) goto out_unmap_regs; } else { par->mmap_map[1].size = SBUS_MMAP_EMPTY; par->mmap_map[4].size = SBUS_MMAP_EMPTY; par->mmap_map[5].size = SBUS_MMAP_EMPTY; par->mmap_map[6].size = SBUS_MMAP_EMPTY; } info->fix.smem_start = op->resource[0].start; par->which_io = op->resource[0].flags & IORESOURCE_BITS; for (i = 0; i < TCX_MMAP_ENTRIES; i++) { int j; switch (i) { case 10: j = 12; break; case 11: case 12: j = i - 1; break; default: j = i; break; } par->mmap_map[i].poff = op->resource[j].start; } info->flags = FBINFO_DEFAULT; info->fbops = &tcx_ops; /* Initialize brooktree DAC. */ sbus_writel(0x04 << 24, &par->bt->addr); /* color planes */ sbus_writel(0xff << 24, &par->bt->control); sbus_writel(0x05 << 24, &par->bt->addr); sbus_writel(0x00 << 24, &par->bt->control); sbus_writel(0x06 << 24, &par->bt->addr); /* overlay plane */ sbus_writel(0x73 << 24, &par->bt->control); sbus_writel(0x07 << 24, &par->bt->addr); sbus_writel(0x00 << 24, &par->bt->control); tcx_reset(info); tcx_blank(FB_BLANK_UNBLANK, info); if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_regs; fb_set_cmap(&info->cmap, info); tcx_init_fix(info, linebytes); err = register_framebuffer(info); if (err < 0) goto out_dealloc_cmap; dev_set_drvdata(&op->dev, info); printk(KERN_INFO "%s: TCX at %lx:%lx, %s\n", dp->full_name, par->which_io, info->fix.smem_start, par->lowdepth ? "8-bit only" : "24-bit depth"); return 0; out_dealloc_cmap: fb_dealloc_cmap(&info->cmap); out_unmap_regs: tcx_unmap_regs(op, info, par); framebuffer_release(info); out_err: return err; }
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; }
__s32 Display_Fb_Request(__u32 sel, __disp_fb_create_para_t *fb_para) { struct fb_info *fbinfo = NULL; fb_info_t * fbi = &g_fbi; __s32 hdl = 0; __disp_layer_info_t layer_para; int ret; __msg("Display_Fb_Request, sel=%d\n", sel); fbinfo = framebuffer_alloc(0, fbi->dev); fbinfo->fbops = &dispfb_ops; fbinfo->flags = 0; fbinfo->device = fbi->dev; fbinfo->par = fbi; fbinfo->var.xoffset = 0; fbinfo->var.yoffset = 0; fbinfo->var.xres = 1; fbinfo->var.yres = 1; fbinfo->var.xres_virtual = 1; fbinfo->var.yres_virtual = 1; fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; fbinfo->fix.type_aux = 0; fbinfo->fix.visual = FB_VISUAL_TRUECOLOR; fbinfo->fix.xpanstep = 1; fbinfo->fix.ypanstep = 1; fbinfo->fix.ywrapstep = 0; fbinfo->fix.accel = FB_ACCEL_NONE; fbinfo->fix.line_length = 0; fbinfo->fix.smem_len = fb_para->smem_len; ret = Fb_map_video_memory(fbinfo); if (ret) { __wrn("Failed to allocate video RAM: %d\n", ret); return DIS_FAIL; } hdl = BSP_disp_layer_request(sel, fb_para->mode); layer_para.mode = fb_para->mode; layer_para.pipe = 0; layer_para.alpha_en = 0; layer_para.alpha_val = 0xff; layer_para.ck_enable = 0; layer_para.src_win.x = 0; layer_para.src_win.y = 0; layer_para.src_win.width = 1; layer_para.src_win.height = 1; layer_para.scn_win.x = 0; layer_para.scn_win.y = 0; layer_para.scn_win.width = 1; layer_para.scn_win.height = 1; layer_para.fb.addr[0] = (__u32)fbinfo->fix.smem_start; layer_para.fb.addr[1] = (__u32)fbinfo->fix.smem_start+fb_para->ch1_offset; layer_para.fb.addr[2] = (__u32)fbinfo->fix.smem_start+fb_para->ch2_offset; layer_para.fb.size.width = 1; layer_para.fb.size.height = 1; layer_para.fb.format = DISP_FORMAT_ARGB8888; layer_para.fb.seq = DISP_SEQ_ARGB; layer_para.fb.mode = DISP_MOD_INTERLEAVED; layer_para.fb.br_swap = 0; layer_para.fb.cs_mode = DISP_BT601; BSP_disp_layer_set_para(sel, hdl, &layer_para); BSP_disp_layer_open(sel, hdl); register_framebuffer(fbinfo); fbi->fb_screen_id[fbinfo->node] = sel; fbi->layer_hdl[fbinfo->node] = hdl; fbi->fbinfo[fbinfo->node] = fbinfo; fbi->fb_num++; return hdl; }