Frame buffer分析 - fbcvt.c modedb.c

来源:互联网 发布:p图软件哪个好 编辑:程序博客网 时间:2024/05/17 02:02

参照Documentation/fb/modedb.txt

CVT: Coordinated Video Timings

From the VESA(TM) Website:
     "The purpose of CVT is to provide a method for generating a consistent
      and coordinated set of standard formats, display refresh rates, and
      timing specifications for computer display products, both those
      employing CRTs, and those using other display technologies. The
      intention of CVT is to give both source and display manufacturers a
      common set of tools to enable new timings to be developed in a
      consistent manner that ensures greater compatibility."

CVT引入了新的命名规范,如下

<pix>M<a>[-R]

pix = 像素总数,单位为MB(xres x yres)

M = 一直存在

a = 外观比例 (3 - 4:3; 4 - 5:4; 9 - 16:9; A - 16:10)

-R = reduced blanking

CVT例子: .48M3-R - 800 x 600 with reduced blanking

注意标准CVT timing有如下限制:

- 外观比例必须是上面列出的3, 4, 9, A

- 可接受的刷新率是50, 60, 70, 85Hz

- 如果是reduced blanking, 刷新率必须是60Hz


 35 struct fb_cvt_data {
 36     u32 xres;   /* x 分辨率 */
 37     u32 yres;   /* y 分辨率 */
 38     u32 refresh; /* refresh speed */
 39     u32 f_refresh; /* refresh frequent, if non-interlace  refresh equal to f_refresh, otherwise f_refresh is twice of refresh*/
 40     u32 pixclock;
 41     u32 hperiod;
 42     u32 hblank;  /* 水平消隐 */
 43     u32 hfreq;
 44     u32 htotal; /* 包含active_pixels和hblank, 一个扫描行计时总数 */
 45     u32 vtotal; /* 一场的计时总数,包含有效数据 v_margin vbi数据 */
 46     u32 vsync;  /* vertical sync 计时,根据aspect ratio查表 */
 47     u32 hsync;  /* 水平同步 */
 48     u32 h_front_porch;  /* 行有效数据的前面准备部分,hblank/2 + h_margin - hsync*/
 49     u32 h_back_porch;  /* 行有效数据后面部分, hblank/2 + h_margin */
 50     u32 v_front_porch;   /* vertical 前导,vertial总数减去 v_sync v_back_porch 一场数据  */
 51     u32 v_back_porch;  /* vertical 后缀 v_margin + 3 */
 52     u32 h_margin;  /* 在cvt里面left_margin和right_margin相同,统称为h_margin */
 53     u32 v_margin;  /* 在cvt里面top margin和bottom margin相同,数值为v_margin = 一场行数 * 1.8%*/
 54     u32 interlace;   /* 1 non-interlace, 2 interlaced */
 55     u32 aspect_ratio; /* width and height resolution ratio */
 56     u32 active_pixels; /* 每个同步行包行的像素个数,这包括left right margin, 但不包括 hblank*/
 57     u32 flags;
 58     u32 status;
 59 };

 72 /* returns hperiod * 1000 */
 73 static u32 fb_cvt_hperiod(struct fb_cvt_data *cvt)
 74 {
 75     u32 num = 1000000000/cvt->f_refresh;
 76     u32 den;
 77 
 78     if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK) {
 79         num -= FB_CVT_RB_MIN_VBLANK * 1000;
 80         den = 2 * (cvt->yres/cvt->interlace + 2 * cvt->v_margin);
 81     } else {
 82         num -= FB_CVT_MIN_VSYNC_BP * 1000;
 83         den = 2 * (cvt->yres/cvt->interlace + cvt->v_margin * 2
 84                + FB_CVT_MIN_VPORCH + cvt->interlace/2);
 85     }
 86 
 87     return 2 * (num/den);
 88 }

该函数计算扫描每行需要的像素数

75 num 每帧需要花费的的时间,单位为picosecond * 1000, 之所以这里不使用picosecond,是因为picosecond单位太小,无法表示

172 static u32 fb_cvt_pixclock(struct fb_cvt_data *cvt)
173 {
174     u32 pixclock;
175 
176     if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
177         pixclock = (cvt->f_refresh * cvt->vtotal * cvt->htotal)/1000;
178     else
179         pixclock = (cvt->htotal * 1000000)/cvt->hperiod;
180 
181     pixclock /= 250;
182     pixclock *= 250;
183     pixclock *= 1000;
184 
185     return pixclock;
186 }
时钟屏率,比如刷新率为60, vtotal=1024, htotal = 1024,并且是Reduced blank,那么时钟屏率为60MHz

pixelclock和刷新率 宽高成正比


188 static u32 fb_cvt_aspect_ratio(struct fb_cvt_data *cvt)
189 {
190     u32 xres = cvt->xres;
191     u32 yres = cvt->yres;
192     u32 aspect = -1;
193 
194     if (xres == (yres * 4)/3 && !((yres * 4) % 3))
195         aspect = 0;
196     else if (xres == (yres * 16)/9 && !((yres * 16) % 9))
197         aspect = 1;
198     else if (xres == (yres * 16)/10 && !((yres * 16) % 10))
199         aspect = 2;
200     else if (xres == (yres * 5)/4 && !((yres * 5) % 4))
201         aspect = 3;
202     else if (xres == (yres * 15)/9 && !((yres * 15) % 9))
203         aspect = 4;
204     else {
205         printk(KERN_INFO "fbcvt: Aspect ratio not CVT "
206                "standard\n");
207         aspect = 7;
208         cvt->status = 1;
209     }
210 
211     return aspect;
212 }
根据cvt->xres和cvt->yres计算aspect ratio

270 static void fb_cvt_convert_to_mode(struct fb_cvt_data *cvt,
271                    struct fb_videomode *mode)
272 {
273     mode->refresh = cvt->f_refresh;
274     mode->pixclock = KHZ2PICOS(cvt->pixclock/1000);
275     mode->left_margin = cvt->h_back_porch;
276     mode->right_margin = cvt->h_front_porch;
277     mode->hsync_len = cvt->hsync;
278     mode->upper_margin = cvt->v_back_porch;
279     mode->lower_margin = cvt->v_front_porch;
280     mode->vsync_len = cvt->vsync;
281 
282     mode->sync &= ~(FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT);
283 
284     if (cvt->flags & FB_CVT_FLAG_REDUCED_BLANK)
285         mode->sync |= FB_SYNC_HOR_HIGH_ACT;
286     else
287         mode->sync |= FB_SYNC_VERT_HIGH_ACT;
288 }

CVT本身是videomode的一种表示方法,这个函数是把CVT表示转换为video mode

从这个转化可以看出 两种表示法对有些定义的差别

1110 struct fb_videomode {
1111     const char *name;   /* optional */
1112     u32 refresh;        /* optional 刷新率*/
1113     u32 xres;       /* x 分辨率 */
1114     u32 yres;      /* y 分辨率 */
1115     u32 pixclock;   /* 一个像像素需要的时间 pico second */
1116     u32 left_margin;
1117     u32 right_margin;
1118     u32 upper_margin;
1119     u32 lower_margin;
1120     u32 hsync_len;   /* 水平同步长度, 单位像素*/
1121     u32 vsync_len;  /* 垂直同步长度, 单位像素*/ 
1122     u32 sync;
1123     u32 vmode;
1124     u32 flag;
1125 };

原创粉丝点击