Frame buffer分析 - fbcvt.c modedb.c .

参照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 };

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值