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