⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mx3fb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{       struct mx3fb_data *drv_data = platform_get_drvdata(pdev);       struct mx3fb_info *mx3_fbi = drv_data->fbi->par;       if (mx3_fbi->blank == FB_BLANK_UNBLANK) {               sdc_enable_channel(mx3_fbi);               sdc_set_brightness(mx3fb, drv_data->backlight_level);       }       acquire_console_sem();       fb_set_suspend(drv_data->fbi, 0);       release_console_sem();       return 0;}#else#define mx3fb_suspend   NULL#define mx3fb_resume    NULL#endif/* * Main framebuffer functions *//** * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. * @fbi:       framebuffer information pointer * @return:    Error code indicating success or failure * * This buffer is remapped into a non-cached, non-buffered, memory region to * allow palette and pixel writes to occur without flushing the cache. Once this * area is remapped, all virtual memory access to the video memory should occur * at the new region. */static int mx3fb_map_video_memory(struct fb_info *fbi){       int retval = 0;       dma_addr_t addr;       fbi->screen_base = dma_alloc_writecombine(fbi->device,                                                 fbi->fix.smem_len,                                                 &addr, GFP_DMA);       if (!fbi->screen_base) {               dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n",                       fbi->fix.smem_len);               retval = -EBUSY;               goto err0;       }       fbi->fix.smem_start = addr;       dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n",               (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len);       fbi->screen_size = fbi->fix.smem_len;       /* Clear the screen */       memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);       return 0;err0:       fbi->fix.smem_len = 0;       fbi->fix.smem_start = 0;       fbi->screen_base = NULL;       return retval;}/** * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. * @fbi:       framebuffer information pointer * @return:    error code indicating success or failure */static int mx3fb_unmap_video_memory(struct fb_info *fbi){       dma_free_writecombine(fbi->device, fbi->fix.smem_len,                             fbi->screen_base, fbi->fix.smem_start);       fbi->screen_base = 0;       fbi->fix.smem_start = 0;       fbi->fix.smem_len = 0;       return 0;}/** * mx3fb_init_fbinfo() - initialize framebuffer information object. * @return:    initialized framebuffer structure. */static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops){       struct fb_info *fbi;       struct mx3fb_info *mx3fbi;       int ret;       /* Allocate sufficient memory for the fb structure */       fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev);       if (!fbi)               return NULL;       mx3fbi                  = fbi->par;       mx3fbi->cookie          = -EINVAL;       mx3fbi->cur_ipu_buf     = 0;       fbi->var.activate       = FB_ACTIVATE_NOW;       fbi->fbops              = ops;       fbi->flags              = FBINFO_FLAG_DEFAULT;       fbi->pseudo_palette     = mx3fbi->pseudo_palette;       mutex_init(&mx3fbi->mutex);       /* Allocate colormap */       ret = fb_alloc_cmap(&fbi->cmap, 16, 0);       if (ret < 0) {               framebuffer_release(fbi);               return NULL;       }       return fbi;}static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan){       struct device *dev = mx3fb->dev;       struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data;       const char *name = mx3fb_pdata->name;       unsigned int irq;       struct fb_info *fbi;       struct mx3fb_info *mx3fbi;       const struct fb_videomode *mode;       int ret, num_modes;       ichan->client = mx3fb;       irq = ichan->eof_irq;       if (ichan->dma_chan.chan_id != IDMAC_SDC_0)               return -EINVAL;       fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops);       if (!fbi)               return -ENOMEM;       if (!fb_mode)               fb_mode = name;       if (!fb_mode) {               ret = -EINVAL;               goto emode;       }       if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) {               mode = mx3fb_pdata->mode;               num_modes = mx3fb_pdata->num_modes;       } else {               mode = mx3fb_modedb;               num_modes = ARRAY_SIZE(mx3fb_modedb);       }       if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode,                         num_modes, NULL, default_bpp)) {               ret = -EBUSY;               goto emode;       }       fb_videomode_to_modelist(mode, num_modes, &fbi->modelist);       /* Default Y virtual size is 2x panel size */       fbi->var.yres_virtual = fbi->var.yres * 2;       mx3fb->fbi = fbi;       /* set Display Interface clock period */       mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER);       /* Might need to trigger HSP clock change - see 44.3.3.8.5 */       sdc_set_brightness(mx3fb, 255);       sdc_set_global_alpha(mx3fb, true, 0xFF);       sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0);       mx3fbi                  = fbi->par;       mx3fbi->idmac_channel   = ichan;       mx3fbi->ipu_ch          = ichan->dma_chan.chan_id;       mx3fbi->mx3fb           = mx3fb;       mx3fbi->blank           = FB_BLANK_NORMAL;       init_completion(&mx3fbi->flip_cmpl);       disable_irq(ichan->eof_irq);       dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq);       ret = mx3fb_set_par(fbi);       if (ret < 0)               goto esetpar;       mx3fb_blank(FB_BLANK_UNBLANK, fbi);       dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode);       ret = register_framebuffer(fbi);       if (ret < 0)               goto erfb;       return 0;erfb:esetpar:emode:       fb_dealloc_cmap(&fbi->cmap);       framebuffer_release(fbi);       return ret;}static bool chan_filter(struct dma_chan *chan, void *arg){       struct dma_chan_request *rq = arg;       struct device *dev;       struct mx3fb_platform_data *mx3fb_pdata;       if (!rq)               return false;       dev = rq->mx3fb->dev;       mx3fb_pdata = dev->platform_data;       return rq->id == chan->chan_id &&               mx3fb_pdata->dma_dev == chan->device->dev;}static void release_fbi(struct fb_info *fbi){       mx3fb_unmap_video_memory(fbi);       fb_dealloc_cmap(&fbi->cmap);       unregister_framebuffer(fbi);       framebuffer_release(fbi);}static int mx3fb_probe(struct platform_device *pdev){       struct device *dev = &pdev->dev;       int ret;       struct resource *sdc_reg;       struct mx3fb_data *mx3fb;       dma_cap_mask_t mask;       struct dma_chan *chan;       struct dma_chan_request rq;       /*        * Display Interface (DI) and Synchronous Display Controller (SDC)        * registers        */       sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);       if (!sdc_reg)               return -EINVAL;       mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL);       if (!mx3fb)               return -ENOMEM;       spin_lock_init(&mx3fb->lock);       mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg));       if (!mx3fb->reg_base) {               ret = -ENOMEM;               goto eremap;       }       pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end,                mx3fb->reg_base);       /* IDMAC interface */       dmaengine_get();       mx3fb->dev = dev;       platform_set_drvdata(pdev, mx3fb);       rq.mx3fb = mx3fb;       dma_cap_zero(mask);       dma_cap_set(DMA_SLAVE, mask);       dma_cap_set(DMA_PRIVATE, mask);       rq.id = IDMAC_SDC_0;       chan = dma_request_channel(mask, chan_filter, &rq);       if (!chan) {               ret = -EBUSY;               goto ersdc0;       }       ret = init_fb_chan(mx3fb, to_idmac_chan(chan));       if (ret < 0)               goto eisdc0;       mx3fb->backlight_level = 255;       return 0;eisdc0:       dma_release_channel(chan);ersdc0:       dmaengine_put();       iounmap(mx3fb->reg_base);eremap:       kfree(mx3fb);       dev_err(dev, "mx3fb: failed to register fb\n");       return ret;}static int mx3fb_remove(struct platform_device *dev){       struct mx3fb_data *mx3fb = platform_get_drvdata(dev);       struct fb_info *fbi = mx3fb->fbi;       struct mx3fb_info *mx3_fbi = fbi->par;       struct dma_chan *chan;       chan = &mx3_fbi->idmac_channel->dma_chan;       release_fbi(fbi);       dma_release_channel(chan);       dmaengine_put();       iounmap(mx3fb->reg_base);       kfree(mx3fb);       return 0;}static struct platform_driver mx3fb_driver = {       .driver = {                  .name = MX3FB_NAME,       },       .probe = mx3fb_probe,       .remove = mx3fb_remove,       .suspend = mx3fb_suspend,       .resume = mx3fb_resume,};/* * Parse user specified options (`video=mx3fb:') * example: *     video=mx3fb:bpp=16 */static int mx3fb_setup(void){#ifndef MODULE       char *opt, *options = NULL;       if (fb_get_options("mx3fb", &options))               return -ENODEV;       if (!options || !*options)               return 0;       while ((opt = strsep(&options, ",")) != NULL) {               if (!*opt)                       continue;               if (!strncmp(opt, "bpp=", 4))                       default_bpp = simple_strtoul(opt + 4, NULL, 0);               else                       fb_mode = opt;       }#endif       return 0;}static int __init mx3fb_init(void){       int ret = mx3fb_setup();       if (ret < 0)               return ret;       ret = platform_driver_register(&mx3fb_driver);       return ret;}static void __exit mx3fb_exit(void){       platform_driver_unregister(&mx3fb_driver);}module_init(mx3fb_init);module_exit(mx3fb_exit);MODULE_AUTHOR("Freescale Semiconductor, Inc.");MODULE_DESCRIPTION("MX3 framebuffer driver");MODULE_ALIAS("platform:" MX3FB_NAME);MODULE_LICENSE("GPL v2");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -