1、struct fb_info数据结构(FBI)
FBI 中记录了帧缓冲设备的全部信息,包括设备的设置参数、状态以及操作函数指针。每一个帧缓冲设备都必须对应一个 FBI。
1 struct fb_info
2 {3 int node;
4 int flags;
5 struct fb_var_screeninfo var; /*可变参数 */
6 struct fb_fix_screeninfo fix; /*固定参数 */
7 struct fb_monspecs monspecs; /*显示器标准 */
8 struct work_struct queue; /* 帧缓冲事件队列 */
9 struct fb_pixmap pixmap; /* 图像硬件mapper */
10 struct fb_pixmap sprite; /* 光标硬件mapper */
11 struct fb_cmap cmap; /* 目前的颜色表*/
12 struct list_head modelist;
13 struct fb_videomode *mode; /* 目前的video模式 */
14
15 #ifdef CONFIG_FB_BACKLIGHT
16 struct mutex bl_mutex;
17 /* 对应的背光设备 */
18 struct backlight_device *bl_dev;
19 /* 背光调整 */
20 u8 bl_curve[FB_BACKLIGHT_LEVELS];
21 #endif
22
23 struct fb_ops *fbops; /* fb_ops,帧缓冲操作 */
24 struct device *device;
25 struct class_device *class_device; /
26 int class_flag; /* 私有sysfs标志 */
27 #ifdef CONFIG_FB_TILEBLITTING
28 struct fb_tile_ops *tileops; /* 图块Blitting */
29 #endif
30 char _ _iomem *screen_base; /* 虚拟基地址 */
31 unsigned long screen_size; /* ioremapped的虚拟内存大小 */
32 void *pseudo_palette; /* 伪16色颜色表 */
33 #define FBINFO_STATE_RUNNING 0
34 #define FBINFO_STATE_SUSPENDED 1
35 u32 state; /* 硬件状态,如挂起 */
36 void *fbcon_par;
37 void *par;
38 };
2 fb_ops结构体
FBI 的成员变量 fb_ops 为指向底层操作的函数的指针,这些函数是需要驱动程序开发人员编写的。
1 struct fb_ops
2 {
3 struct module *owner;
4 /* 打开/释放 */
5 int(*fb_open)(struct fb_info *info, int user);
6 int(*fb_release)(struct fb_info *info, int user);
7
8 /* 对于非线性布局的/常规内存映射无法工作的帧缓冲设备需要 */
9 ssize_t(*fb_read)(struct file *file, char _ _user *buf, size_t
count,
10 loff_t*ppos);
11 ssize_t(*fb_write)(struct file *file, const char _ _user *buf,
size_t count,
12 loff_t *ppos);
13
14 /* 检测可变参数,并调整到支持的值*/
15 int(*fb_check_var)(struct fb_var_screeninfo *var, struct
fb_info *info);
16
17 /* 根据info->var设置video模式 */
int(*fb_set_par)(struct fb_info *info);
19
20 /* 设置color寄存器 */
21 int(*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
unsigned
22 blue, unsigned transp, struct fb_info *info);
23
24 /* 批量设置color寄存器,设置颜色表 */
25 int(*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
26
27 /*显示空白 */
28 int(*fb_blank)(int blank, struct fb_info *info);
29
30 /* pan显示 */
31 int(*fb_pan_display)(struct fb_var_screeninfo *var, struct
fb_info *info);
32
33 /* 矩形填充 */
34 void(*fb_fillrect)(struct fb_info *info, const struct
fb_fillrect *rect);
35 /* 数据复制 */
36 void(*fb_copyarea)(struct fb_info *info, const struct
fb_copyarea *region);
37 /* 图形填充 */
38 void(*fb_imageblit)(struct fb_info *info, const struct fb_image
*image);
39
40 /* 绘制光标 */
41 int(*fb_cursor)(struct fb_info *info, struct fb_cursor *cursor);
42
43 /* 旋转显示 */
44 void(*fb_rotate)(struct fb_info *info, int angle);
45
46 /* 等待blit空闲 (可选) */
47 int(*fb_sync)(struct fb_info *info);
48
49 /* fb特定的ioctl (可选) */
50 int(*fb_ioctl)(struct fb_info *info, unsigned int cmd, unsigned
long arg);
51
52 /* 处理32位的compat ioctl (可选) */
53 int(*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);
54
55 /* fb特定的mmap */
56 int(*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
57
58 /* 保存目前的硬件状态 */
59 void(*fb_save_state)(struct fb_info *info);
60
61 /* 恢复被保存的硬件状态 */
62 void(*fb_restore_state)(struct fb_info *info);
63 };
在mach-smdk2410.c中,定义了初始的LCD参数。注意这是个全局变量。
static struct s3c2410fb_mach_info smdk2410_lcd_cfg = {
.regs= {
.lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
S3C2410_LCDCON1_TFT|
S3C2410_LCDCON1_CLKVAL(7),
......
},
.width = 240, .height = 320,
.xres = {.min = 240,.max= 240,.defval = 240},
.bpp = {.min = 16, .max= 16, .defval = 16},
......
};
(2)内核初始化时候调用s3c2410fb_probe函数。下面分析这个函数的做的工作。首先先动态分配s3c2410fb_info空间。
fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info),&pdev->dev);
把域mach_info指向mach-smdk2410.c中的smdk2410_lcd_cfg 。
info->mach_info = pdev->dev.platform_data;
设置fb_info域的fix,var,fops字段。
fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
fbinfo->fix.type_aux = 0;
fbinfo->fix.xpanstep = 0;
fbinfo->var.nonstd = 0;
fbinfo->var.activate = FB_ACTIVATE_NOW;
fbinfo->var.height = mach_info->height;
fbinfo->var.width = mach_info->width;
fbinfo->fbops = &s3c2410fb_ops;
……
该函数调用s3c2410fb_map_video_memory()申请DMA内存,即显存。
fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE);
fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
&fbi->map_dma, GFP_KERNEL);
fbi->map_size = fbi->fb->fix.smem_len;
…….
设置控制寄存器,设置硬件寄存器。
memcpy(&info->regs, &mach_info->regs,sizeof(info->regs));
info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
……….
调用函数s3c2410fb_init_registers(),把初始值写入寄存器。
writel(fbi->regs.lcdcon1, S3C2410_LCDCON1);
writel(fbi->regs.lcdcon2, S3C2410_LCDCON2);
(3)当用户调用mmap()映射内存的时候,Fbmem.c把刚才设置好的显存区域映射给用户。
start = info->fix.smem_start;
len = PAGE_ALIGN( (start & ~PAGE_MASK) + info->fix.smem_len);
io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,vma->vm_page_prot);
……
这样就完成了驱动初始化到用户调用的整个过程。
最后
以上就是谦让店员最近收集整理的关于Frambuff基础的全部内容,更多相关Frambuff基础内容请搜索靠谱客的其他文章。
发表评论 取消回复