📄 omap_fb.c
字号:
switch(fb_out_layer){ case OMAP2_GRAPHICS: p = sprintf(buf, "gfx\n"); break; case OMAP2_VIDEO1: p = sprintf(buf, "video1\n"); break; case OMAP2_VIDEO2: p = sprintf(buf, "video2\n"); break; } return(p);}static ssize_twrite_fb_out(const char *buffer, size_t count){ int out_layer; if(!buffer || (count == 0)) return 0; /* Only 'lcd' or 'tv' are valid inputs */ if(strncmp(buffer, "gmx", 3) == 0) out_layer = OMAP2_GRAPHICS; else if(strncmp(buffer, "video1", 6) == 0) out_layer = OMAP2_VIDEO1; else if(strncmp(buffer, "video2", 6) == 0) out_layer = OMAP2_VIDEO2; else return -EINVAL; if(out_layer != fb_out_layer){ /* switch the output layer */ /* check if the pipeline is available */ if(omap2_disp_request_layer(out_layer)){ omap2_disp_start_gfxlayer(); fb_out_layer = out_layer; omap24xxfb_set_output_layer(out_layer); } } return count;}ssize_tfb_out_show(struct class_device *cdev, char *buf){ return(read_fb_out(buf));}ssize_tfb_out_store(struct class_device *cdev, const char *buffer, size_t count){ return(write_fb_out(buffer,count));}/* * Initialization */int __init omap24xxfb_init(void){ struct omap24xxfb_info *oinfo; struct fb_info *info; int output_dev = omap2_disp_get_output_dev(OMAP2_GRAPHICS); DBGENTER; /* Register the driver with LDM */ if (platform_driver_register(&omap24xxfb_driver)) { printk(KERN_ERR FB_NAME ": failed to register omapfb driver\n"); return -ENODEV; } /* Register the device with LDM */ if (platform_device_register(&omap24xxfb_device)) { printk(KERN_ERR FB_NAME ": failed to register omapfb device\n"); goto unregister_driver; } awake = 1; fb_suspend_data.suspended = 0; init_waitqueue_head(&fb_suspend_data.suspend_wq); { char *option; if (fb_get_options("omap24xxfb", &option)) { return -ENODEV; } omap24xxfb_setup(option); // parse options } oinfo = kmalloc(sizeof(struct omap24xxfb_info), GFP_KERNEL); if (!oinfo) { printk(KERN_ERR FB_NAME ": could not allocate memory\n"); goto unregister_device; } memset(oinfo, 0, sizeof(struct omap24xxfb_info)); saved_oinfo = oinfo; oinfo->rotation_support = (omap24xxfb_rotation >= 0) ? 1 : 0; /* set the period (in picoseconds) of the graphics timebase */ oinfo->gfx_clk_period = omap24xxfb_gfx_clk_period(); /* Set base addrs */ oinfo->fb_base_phys = omap24xxfb_fb_base(); oinfo->fb_size = omap24xxfb_fb_size(oinfo->rotation_support); if (oinfo->rotation_support) { oinfo->vrfb_size = omap24xxfb_vrfb_size(); oinfo->rotation_deg = omap24xxfb_rotation; } oinfo->mmio_base_phys = DSS_REG_BASE; /* A null base address indicates that the framebuffer memory should be * dynamically allocated. */ if (!oinfo->fb_base_phys) oinfo->alloc_fb_mem = 1; /* request the mem regions */ if (!request_mem_region(oinfo->mmio_base_phys, DSS_REG_SIZE, FB_NAME)) { printk(KERN_ERR FB_NAME ": cannot reserve MMIO region\n"); goto free_par; } if (!oinfo->alloc_fb_mem) { if (!request_mem_region(oinfo->fb_base_phys, oinfo->fb_size, FB_NAME)) { printk(KERN_ERR FB_NAME ": cannot reserve FB region\n"); goto release_mmio; } } if (oinfo->rotation_support) { oinfo->sms_rot_phy[0] = SMS_ROT_VIRT_BASE(0, 0); oinfo->sms_rot_phy[1] = SMS_ROT_VIRT_BASE(0, 90); oinfo->sms_rot_phy[2] = SMS_ROT_VIRT_BASE(0, 180); oinfo->sms_rot_phy[3] = SMS_ROT_VIRT_BASE(0, 270); if (!request_mem_region(oinfo->sms_rot_phy[0], oinfo->vrfb_size, FB_NAME)) { printk(KERN_ERR FB_NAME ": cannot reserve FB region for 0 deg\n"); goto release_fb; } if (!request_mem_region(oinfo->sms_rot_phy[1], oinfo->vrfb_size, FB_NAME)) { printk(KERN_ERR FB_NAME ": cannot reserve FB region for 90 deg\n"); goto release_rot_0; } if (!request_mem_region(oinfo->sms_rot_phy[2], oinfo->vrfb_size, FB_NAME)) { printk(KERN_ERR FB_NAME ": cannot reserve FB region for 180 deg\n"); goto release_rot_90; } if (!request_mem_region(oinfo->sms_rot_phy[3], oinfo->vrfb_size, FB_NAME)) { printk(KERN_ERR FB_NAME ": cannot reserve FB region for 270 deg\n"); goto release_rot_180; } } /* map the regions */ oinfo->mmio_base = (unsigned long) ioremap(oinfo->mmio_base_phys, DSS_REG_SIZE); if (!oinfo->mmio_base) { printk(KERN_ERR FB_NAME ": cannot map MMIO\n"); if (oinfo->rotation_support) goto release_rot_270; else goto release_fb; } if (!oinfo->alloc_fb_mem) { oinfo->fb_base = (unsigned long) ioremap(oinfo->fb_base_phys, oinfo->fb_size); if (!oinfo->fb_base) { printk(KERN_ERR FB_NAME ": cannot map framebuffer\n"); goto unmap_mmio; } } else { /* allocate coherent memory for the framebuffer */ oinfo->fb_base = (unsigned long) dma_alloc_coherent(NULL, oinfo->fb_size, &oinfo->fb_base_phys, GFP_KERNEL | GFP_DMA); if (!oinfo->fb_base) { printk(KERN_ERR FB_NAME ": cannot allocate " "framebuffer\n"); goto unmap_mmio; } } memset((void *)oinfo->fb_base, 0, oinfo->fb_size); if (oinfo->rotation_support) { if (!(oinfo->sms_rot_virt[0] = (unsigned long) ioremap(oinfo->sms_rot_phy[0], oinfo->vrfb_size)) || !(oinfo->sms_rot_virt[1] = (unsigned long) ioremap(oinfo->sms_rot_phy[1], oinfo->vrfb_size)) || !(oinfo->sms_rot_virt[2] = (unsigned long) ioremap(oinfo->sms_rot_phy[2], oinfo->vrfb_size)) || !(oinfo->sms_rot_virt[3] = (unsigned long) ioremap(oinfo->sms_rot_phy[3], oinfo->vrfb_size))) { printk(KERN_ERR FB_NAME ": cannot map rotated view(s)\n"); goto unmap_rot; } } /* allocate coherent memory for the palette */ oinfo->palette = (u32 *) dma_alloc_coherent(NULL, sizeof(u32)*256, &oinfo->palette_phys, GFP_KERNEL | GFP_DMA); if (!oinfo->palette) { printk(KERN_ERR FB_NAME ": cannot allocate palette memory\n"); goto unmap_rot; } memset(oinfo->palette, 0, sizeof(u32)*256); if(!omap2_disp_request_layer(OMAP2_GRAPHICS)) { printk(KERN_ERR FB_NAME ": cannot use hw graphics layer\n"); goto free_palette; } /* first enable the power to RGB lines.. then turhn on the LCD.. * as per the SHARP LCD specs */ omap2_dss_rgb_enable(); // enable_backlight(); omap2_disp_get_dss(); /* unblank--enable display controller */ omap2_disp_enable_layer(OMAP2_GRAPHICS); omap2_disp_enable_output_dev(OMAP2_OUTPUT_LCD); omap2_disp_enable_output_dev(OMAP2_OUTPUT_TV); udelay(20); enable_backlight(); /* initialize the fb_info structure */ info = &oinfo->info; info->flags = FBINFO_DEFAULT; info->fbops = &omap24xxfb_ops; if (oinfo->rotation_support){ /* If mirroring in rotation is enabled by default */ if(omap24xxfb_mirroring == 1){ info->screen_base = (char *) (oinfo->sms_rot_virt[omap_rot_mirror_index(oinfo->rotation_deg)]); } else{ info->screen_base = (char *) (oinfo->sms_rot_virt[omap_rotation_index(oinfo->rotation_deg)]); } } else info->screen_base = (char *)(oinfo->fb_base); info->pseudo_palette = oinfo->pseudo_palette; info->par = oinfo; /* Initialize variable screeninfo. * The variable screeninfo can be directly specified by the user * via an ioctl. */ memcpy(&info->var, omap24xxfb_default_var(), sizeof(info->var)); info->var.activate = FB_ACTIVATE_NOW; /* Initialize fixed screeninfo. * The fixed screeninfo cannot be directly specified by the user, but * it may change to reflect changes to the var info. */ strlcpy(info->fix.id, FB_NAME, sizeof(info->fix.id)); if (oinfo->rotation_support) { /* If mirroring in rotation is enabled by default */ if(omap24xxfb_mirroring == 1){ info->fix.smem_start = oinfo->sms_rot_phy[omap_rot_mirror_index(oinfo->rotation_deg)]; } else{ info->fix.smem_start = oinfo->sms_rot_phy[omap_rotation_index(oinfo->rotation_deg)]; } info->fix.line_length = MAX_PIXELS_PER_LINE * info->var.bits_per_pixel / 8; } else { info->fix.smem_start = oinfo->fb_base_phys; info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8; } if (oinfo->rotation_support) info->fix.smem_len = oinfo->vrfb_size; else info->fix.smem_len = oinfo->fb_size; info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = ((var_to_depth(&info->var) <= 8) ? FB_VISUAL_PSEUDOCOLOR: FB_VISUAL_TRUECOLOR); info->fix.xpanstep = 0; info->fix.ypanstep = 1; if(oinfo->rotation_support) info->fix.ypanstep = 0; info->fix.ywrapstep = 0; info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8; info->fix.type_aux = 0; info->fix.mmio_start = oinfo->mmio_base_phys; info->fix.mmio_len = DSS_REG_SIZE; info->fix.accel = FB_ACCEL_NONE; /* Allocate the color map to the maximum size. * Color depths greater than 8 bits are true color and use a 16-bit * pseudo-palette instead of an actual palette, so the maximum color * map size is 256 colors. */ if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { printk(KERN_ERR FB_NAME ": cannot allocate color map\n"); goto put_dss; } if (omap24xxfb_check_var(&info->var, info)) { printk(KERN_ERR FB_NAME ": invalid default video mode\n"); goto dealloc_cmap; } oinfo->timeout = HZ/5; /* initialize the vsync wait queue */ init_waitqueue_head(&oinfo->vsync_wait); /* install our interrupt service routine */ if (omap2_disp_register_isr(omap24xxfb_isr, oinfo,0)) { printk(KERN_ERR FB_NAME ": could not install interrupt service routine\n"); goto dealloc_cmap; }; omap24xxfb_set_par(info); if (register_framebuffer((struct fb_info *) oinfo) < 0) { printk(KERN_ERR FB_NAME ": could not register framebuffer\n"); goto uninstall_isr; } printk(KERN_INFO FB_NAME ": fb%d frame buffer device %s\n", info->node, (oinfo->rotation_support) ? "(rotation support)" : ""); printk(KERN_INFO FB_NAME ": display mode %dx%dx%d", info->var.xres, info->var.yres, var_to_depth(&info->var)); if (oinfo->rotation_support) printk("@%d ", info->var.rotate); if (output_dev == OMAP2_OUTPUT_LCD){ printk(" hsync %dkHz vsync %dHz", oinfo->hsync/1000, oinfo->vsync); } omap2_disp_save_initstate(OMAP_DSS_DISPC_GENERIC); omap2_disp_save_initstate(OMAP2_GRAPHICS); DBGLEAVE; return 0;uninstall_isr: free_irq(INT_24XX_DSS_IRQ, oinfo); dealloc_cmap: fb_dealloc_cmap(&info->cmap);put_dss: omap2_disp_release_layer(fb_out_layer); omap2_disp_put_dss(); disable_backlight(); omap2_dss_rgb_disable(); free_palette: dma_free_coherent(NULL, sizeof(u32)*256, oinfo->palette, oinfo->palette_phys); if (!oinfo->rotation_support) goto free_fb;unmap_rot: if (oinfo->sms_rot_virt[0]) iounmap((void*)oinfo->sms_rot_virt[0]); if (oinfo->sms_rot_virt[1]) iounmap((void*)oinfo->sms_rot_virt[1]); if (oinfo->sms_rot_virt[2]) iounmap((void*)oinfo->sms_rot_virt[2]); if (oinfo->sms_rot_virt[3]) iounmap((void*)oinfo->sms_rot_virt[3]);free_fb: if (!oinfo->alloc_fb_mem) iounmap((void*)oinfo->fb_base); else dma_free_coherent(NULL, oinfo->fb_size, (void *)oinfo->fb_base, oinfo->fb_base_phys);unmap_mmio: iounmap((void*)oinfo->mmio_base); if (!oinfo->rotation_support) goto release_fb;release_rot_270: release_mem_region(oinfo->sms_rot_phy[0], oinfo->vrfb_size);release_rot_180: release_mem_region(oinfo->sms_rot_phy[1], oinfo->vrfb_size);release_rot_90: release_mem_region(oinfo->sms_rot_phy[2], oinfo->vrfb_size);release_rot_0: release_mem_region(oinfo->sms_rot_phy[3], oinfo->vrfb_size);release_fb: if (!oinfo->alloc_fb_mem) release_mem_region(oinfo->fb_base_phys, oinfo->fb_size);release_mmio: release_mem_region(oinfo->mmio_base_phys, DSS_REG_SIZE);free_par: kfree(oinfo); saved_oinfo = NULL;unregister_device: platform_device_unregister(&omap24xxfb_device);unregister_driver: platform_driver_unregister(&omap24xxfb_driver); DBGLEAVE; return -ENODEV;}/* * Cleanup */static void __exit omap24xxfb_cleanup(void){ struct omap24xxfb_info *oinfo = saved_oinfo; DBGENTER; if (!oinfo) return; if(unregister_framebuffer((struct fb_info *) oinfo) < 0) printk(KERN_ERR "unregister framebuffer error\n"); platform_device_unregister(&omap24xxfb_device); platform_driver_unregister(&omap24xxfb_driver); omap2_disp_put_dss(); omap2_disp_disable_layer(OMAP2_GRAPHICS); omap2_disp_disable_layer(fb_out_layer); disable_backlight(); omap2_dss_rgb_disable(); omap2_disp_release_layer(fb_out_layer); /* uninstall isr */ free_irq(INT_24XX_DSS_IRQ, oinfo); fb_dealloc_cmap(&oinfo->info.cmap); dma_free_coherent(NULL, sizeof(u32)*256, oinfo->palette, oinfo->palette_phys); if (!oinfo->alloc_fb_mem) iounmap((void*)oinfo->fb_base); else dma_free_coherent(NULL, oinfo->fb_size, (void *)oinfo->fb_base, oinfo->fb_base_phys); iounmap((void*)oinfo->mmio_base); if (!oinfo->alloc_fb_mem) release_mem_region(oinfo->fb_base_phys, oinfo->fb_size); release_mem_region(oinfo->mmio_base_phys, DSS_REG_SIZE); if (oinfo->rotation_support) { iounmap((void*)oinfo->sms_rot_virt[0]); iounmap((void*)oinfo->sms_rot_virt[1]); iounmap((void*)oinfo->sms_rot_virt[2]); iounmap((void*)oinfo->sms_rot_virt[3]); release_mem_region(oinfo->sms_rot_phy[0], oinfo->vrfb_size); release_mem_region(oinfo->sms_rot_phy[1], oinfo->vrfb_size); release_mem_region(oinfo->sms_rot_phy[2], oinfo->vrfb_size); release_mem_region(oinfo->sms_rot_phy[3], oinfo->vrfb_size); } kfree(oinfo); saved_oinfo = NULL; printk(KERN_DEBUG "Removed framebuffer module\n"); DBGLEAVE;}/* * Modularization */module_init(omap24xxfb_init);module_exit(omap24xxfb_cleanup);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -