come from :https://blog.csdn.net/u012728256/article/details/70274465
struct fb_info {
int node;
int flags;
struct mutex lock; /* 调用open/release/ioctl时的锁 */
struct mutex mm_lock; /* fb_mmap和smem_*的锁 */
struct fb_var_screeninfo var; /* 当前LCD的可变参数 */
struct fb_fix_screeninfo fix; /* 当前LCD的固定参数 */
struct fb_monspecs monspecs; /* 当前LCD标准 */
struct work_struct queue; /* 帧缓冲工作队列 */
struct fb_pixmap pixmap; /* 图像硬件mapper */
struct fb_pixmap sprite; /* 光标硬件mapper */
struct fb_cmap cmap; /* 当前LCD的颜色表 */
struct list_head modelist; /* mode list */
struct fb_videomode *mode; /* 当前的video模式 */
#ifdef CONFIG_FB_BACKLIGHT
/* 对应的背光设备,在framebuffer之前注册及其之后注销 */
struct backlight_device *bl_dev;
/* 背光等级调整 */
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
struct fb_ops *fbops; /* 帧缓冲底层操作函数接口 */
struct device *device; /* 父设备 */
struct device *dev; /* fb设备*/
int class_flag; /* 私有sysfs标志 */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */
#endif
char __iomem *screen_base; /* 虚拟基地址即framebuffer起始虚拟地址 */
unsigned long screen_size; /* 显存大小 */
void *pseudo_palette; /* 伪16色颜色表 */
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; /* Hardware state i.e suspend */
void *fbcon_par; /* fbcon use-only private area */
/* 私有数据 */
void *par;
/* we need the PCI or similiar aperture base/size not
smem_start/size as smem_start may just be an object
allocated inside the aperture so may not actually overlap */
struct apertures_struct {
unsigned int count;
struct aperture {
resource_size_t base;
resource_size_t size;
} ranges[0];
} *apertures;
};
struct fb_var_screeninfo {
__u32 xres; /* 可视分辨率 */
__u32 yres;
__u32 xres_virtual; /* 虚拟分辨率 */
__u32 yres_virtual;
__u32 xoffset; /* 虚拟到可视之间的偏移 */
__u32 yoffset;
__u32 bits_per_pixel; /* 每个像素点占用的位数 */
__u32 grayscale; /* 非0时指灰度值 */
struct fb_bitfield red; /* fb内存的RGB位域 */
struct fb_bitfield green;
struct fb_bitfield blue;
struct fb_bitfield transp; /* 透明度 */
__u32 nonstd; /* 非0时代指非标准像素格式 */
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* 高度 mm */
__u32 width; /* 宽度 mm */
__u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
/* 时序: 除pixel以外,其他的都以像素时钟为单位 */
__u32 pixclock; /* 像素时钟(皮秒) */
__u32 left_margin; /* 行前肩:从行同步信号到有效数据开始的时钟数 */
__u32 right_margin; /* 行后肩:从有效数据末尾到行同步信号的时钟数 */
__u32 upper_margin; /* 帧前肩:从帧同步信号到有效行开始的行数 */
__u32 lower_margin; /* 帧后肩:从有效行末尾到帧同步信号的行数 */
__u32 hsync_len; /* 行同步信号占用的时钟数 */
__u32 vsync_len; /* 帧同步信号占用的行数 */
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* 旋转角度 */
__u32 reserved[5]; /* 保留备用 */
};
struct fb_fix_screeninfo {
char id[16]; /* 标识符 */
unsigned long smem_start; /* framebuffer的物理起始地址 */
__u32 smem_len; /* framebuffer的长度 */
__u32 type; /* see FB_TYPE_* */
__u32 type_aux; /* 隔行扫描参数 */
__u32 visual; /* see FB_VISUAL_* */
__u16 xpanstep; /* zero if no hardware panning */
__u16 ypanstep; /* zero if no hardware panning */
__u16 ywrapstep; /* zero if no hardware ywrap */
__u32 line_length; /* 一行的字节数 */
unsigned long mmio_start; /* 内存映射I/O的物理起始地址 */
__u32 mmio_len; /* 内存映射I/O的长度 */
__u32 accel;
__u16 reserved[3]; /* 保留备用 */
};
这两个结构体分别记录了显示器可以修改和不可修改的信息,这些数据成员需要在驱动程序中初始化。其中fix.visual代表显示器使用的色彩模式,Linux中支持的色彩模式如下:
#define FB_VISUAL_MONO01 0 /* 黑白. 1=Black 0=White */
#define FB_VISUAL_MONO10 1 /* 黑白. 1=White 0=Black */
#define FB_VISUAL_TRUECOLOR 2 /* 真彩色,由红绿蓝三基色构成*/
#define FB_VISUAL_PSEUDOCOLOR 3 /* 伪彩色,采用索引颜色 */
#define FB_VISUAL_DIRECTCOLOR 4 /* 查表显示 */
#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* 只读的伪彩色 */
fb_bitfield结构体描述每一个像素在显示缓冲区中的组织方式。
struct fb_bitfield {
__u32 offset; /* 位域偏移 */
__u32 length; /* 位域长度 */
__u32 msb_right; /* != 0 : 最高有效位在右边 */
};
struct fb_ops {
/* 打开/释放 */
struct module *owner;
int (*fb_open)(struct fb_info *info, int user);
int (*fb_release)(struct fb_info *info, int user);
/* 下面两个函数是非线性布局的/常规内存映射无法工作的缓冲设备需要的接口 */
ssize_t (*fb_read)(struct fb_info *info, char __user *buf,
size_t count, loff_t *ppos);
ssize_t (*fb_write)(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
/* 检测可变参数并调整到支持的值 */
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
/* 根据info->var设置video模式 */
int (*fb_set_par)(struct fb_info *info);
/* 设置颜色寄存器 */
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info *info);
/* 批量设置颜色寄存器 */
int (*fb_setcmap)(struct fb_cmap *cmap, struct fb_info *info);
/* 清屏 */
int (*fb_blank)(int blank, struct fb_info *info);
/* pan display */
int (*fb_pan_display)(struct fb_var_screeninfo *var, struct fb_info *info);
/* 绘制一个矩形 */
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
/* 拷贝数据 */
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
/* 绘制一幅图像 */
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
/* 绘制光标 */
int (*fb_cursor) (struct fb_info *info, struct fb_cursor *cursor);
/* 旋转显示 */
void (*fb_rotate)(struct fb_info *info, int angle);
/* 等待blit空闲(可选) */
int (*fb_sync)(struct fb_info *info);
/* ioctl函数(可选) */
int (*fb_ioctl)(struct fb_info *info, unsigned int cmd,
unsigned long arg);
/* 32位的compat ioctl(可选) */
int (*fb_compat_ioctl)(struct fb_info *info, unsigned cmd,
unsigned long arg);
/* fb特定的mmap */
int (*fb_mmap)(struct fb_info *info, struct vm_area_struct *vma);
/* 根据var得到显示器的功能信息 */
void (*fb_get_caps)(struct fb_info *info, struct fb_blit_caps *caps,
struct fb_var_screeninfo *var);
/* 销毁fb */
void (*fb_destroy)(struct fb_info *info);
};
二、framebuffer注册流程分析
static struct platform_driver tccfb_driver = { // 底层函数接口
.probe = tccfb_probe,
.remove = tccfb_remove,
.suspend = tccfb_suspend,
.shutdown = tccfb_shutdown,
.resume = tccfb_resume,
.driver = {
.name = "tccxxx-lcd",
.owner = THIS_MODULE,
},
};
static int __init tccfb_init(void)
{
printk(KERN_INFO " %s (built %s %s)\n", __func__, __DATE__, __TIME__);
fb_power_state = 1;
tca_fb_init(); // 初始化控制器
#ifdef TCC_VIDEO_DISPLAY_BY_VSYNC_INT // 初始化锁
spin_lock_init(&vsync_lock) ;
spin_lock_init(&vsync_lockDisp ) ;
#endif
return platform_driver_register(&tccfb_driver);
}
static void __exit tccfb_cleanup(void)
{
tca_fb_cleanup(); // 注销控制器
platform_driver_unregister(&tccfb_driver);
}
module_init(tccfb_init);
module_exit(tccfb_cleanup);
struct tccfb_info {
struct fb_info *fb; // fbi结构体
struct device *dev;
//struct tccfb_mach_info *mach_info;
/* raw memory addresses */
dma_addr_t map_dma; /* physical */
u_char * map_cpu; /* virtual */
u_int map_size;
/* addresses of pieces placed in raw buffer */
u_char * screen_cpu; /* virtual address of buffer */
dma_addr_t screen_dma; /* physical address of buffer */
u_int imgch;
struct tccfb_platform_data *pdata;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
struct early_suspend earlier_suspend;
#endif
};