33 #include <linux/list.h>
35 #include <linux/export.h>
51 DRM_DEBUG_KMS(
"Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d "
84 #define HV_FACTOR 1000
90 #define CVT_MARGIN_PERCENTAGE 18
92 #define CVT_H_GRANULARITY 8
94 #define CVT_MIN_V_PORCH 3
96 #define CVT_MIN_V_BPORCH 6
98 #define CVT_CLOCK_STEP 250
100 unsigned int vfieldrate, hperiod;
101 int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin,
vsync;
117 vfieldrate = vrefresh * 2;
131 drm_mode->
hdisplay = hdisplay_rnd + 2 * hmargin;
135 vdisplay_rnd = vdisplay / 2;
144 drm_mode->
vdisplay = vdisplay + 2 * vmargin;
153 if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay))
155 else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay))
157 else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay))
159 else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay))
161 else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay))
172 #define CVT_MIN_VSYNC_BP 550
174 #define CVT_HSYNC_PERCENTAGE 8
175 unsigned int hblank_percentage;
176 int vsyncandback_porch, vback_porch, hblank;
183 hperiod = tmp1 * 2 / (tmp2 * vfieldrate);
190 vsyncandback_porch =
tmp1;
192 vback_porch = vsyncandback_porch -
vsync;
193 drm_mode->
vtotal = vdisplay_rnd + 2 * vmargin +
197 #define CVT_M_FACTOR 600
199 #define CVT_C_FACTOR 40
201 #define CVT_K_FACTOR 128
203 #define CVT_J_FACTOR 20
204 #define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256)
205 #define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
213 hblank = drm_mode->
hdisplay * hblank_percentage /
229 #define CVT_RB_MIN_VBLANK 460
231 #define CVT_RB_H_SYNC 32
233 #define CVT_RB_H_BLANK 160
235 #define CVT_RB_VFPORCH 3
241 tmp2 = vdisplay_rnd + 2 * vmargin;
242 hperiod = tmp1 / (tmp2 * vfieldrate);
249 drm_mode->
vtotal = vdisplay_rnd + 2 * vmargin + vbilines;
303 int GTF_M,
int GTF_2C,
int GTF_K,
int GTF_2J)
305 #define GTF_MARGIN_PERCENTAGE 18
307 #define GTF_CELL_GRAN 8
309 #define GTF_MIN_V_PORCH 1
313 #define H_SYNC_PERCENT 8
315 #define MIN_VSYNC_PLUS_BP 550
317 #define GTF_C_PRIME ((((GTF_2C - GTF_2J) * GTF_K / 256) + GTF_2J) / 2)
318 #define GTF_M_PRIME (GTF_K * GTF_M / 256)
320 unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd;
321 int top_margin, bottom_margin;
323 unsigned int hfreq_est;
324 int vsync_plus_bp, vback_porch;
325 unsigned int vtotal_lines, vfieldrate_est, hperiod;
326 unsigned int vfield_rate, vframe_rate;
327 int left_margin, right_margin;
328 unsigned int total_active_pixels, ideal_duty_cycle;
329 unsigned int hblank, total_pixels, pixel_freq;
330 int hsync, hfront_porch, vodd_front_porch_lines;
331 unsigned int tmp1, tmp2;
350 vdisplay_rnd = vdisplay / 2;
356 vfieldrate_rqd = vrefresh * 2;
366 bottom_margin = top_margin;
379 hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1;
385 vsync_plus_bp = (vsync_plus_bp + 500) / 1000;
389 vtotal_lines = vdisplay_rnd + top_margin + bottom_margin +
392 vfieldrate_est = hfreq_est / vtotal_lines;
394 hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines);
397 vfield_rate = hfreq_est / vtotal_lines;
400 vframe_rate = vfield_rate / 2;
402 vframe_rate = vfield_rate;
411 right_margin = left_margin;
413 total_active_pixels = hdisplay_rnd + left_margin + right_margin;
419 hblank = total_active_pixels * ideal_duty_cycle /
420 (100000 - ideal_duty_cycle);
421 hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN);
422 hblank = hblank * 2 * GTF_CELL_GRAN;
424 total_pixels = total_active_pixels + hblank;
426 pixel_freq = total_pixels * hfreq_est / 1000;
433 hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN;
434 hsync = hsync * GTF_CELL_GRAN;
436 hfront_porch = hblank / 2 -
hsync;
438 vodd_front_porch_lines = GTF_MIN_V_PORCH ;
442 drm_mode->
hsync_start = hdisplay_rnd + hfront_porch;
444 drm_mode->
htotal = total_pixels;
446 drm_mode->
vsync_start = vdisplay_rnd + vodd_front_porch_lines;
448 drm_mode->
vtotal = vtotal_lines;
450 drm_mode->
clock = pixel_freq;
458 if (GTF_M == 600 && GTF_2C == 80 && GTF_K == 128 && GTF_2J == 40)
500 bool lace,
int margins)
503 margins, 600, 40 * 2, 128, 20 * 2);
522 interlaced ?
"i" :
"");
542 list_move_tail(entry,
new);
598 unsigned int calc_val;
633 unsigned int calc_val;
641 calc_val = (mode->
clock * 1000);
643 refresh = (calc_val + vtotal / 2) / vtotal;
650 refresh /= mode->
vscan;
725 int id = dst->
base.id;
729 INIT_LIST_HEAD(&dst->
head);
815 int maxX,
int maxY,
int maxPitch)
820 if (maxPitch > 0 && mode->
hdisplay > maxPitch)
823 if (maxX > 0 && mode->
hdisplay > maxX)
826 if (maxY > 0 && mode->
vdisplay > maxY)
850 int *
min,
int *
max,
int n_ranges)
857 for (i = 0; i < n_ranges; i++) {
858 if (mode->
clock >= min[i] && mode->
clock <= max[i]) {
892 DRM_DEBUG_KMS(
"Not using %s mode %d\n",
985 list_move_tail(&pmode->
head, &connector->
modes);
1006 struct drm_cmdline_mode *
mode)
1010 bool res_specified =
false, bpp_specified =
false, refresh_specified =
false;
1011 unsigned int xres = 0, yres = 0,
bpp = 32, refresh = 0;
1012 bool yres_specified =
false,
cvt =
false,
rb =
false;
1013 bool interlace =
false, margins =
false, was_digit =
false;
1023 mode->specified =
false;
1029 for (i = namelen-1; i >= 0; i--) {
1032 if (!refresh_specified && !bpp_specified &&
1033 !yres_specified && !
cvt && !
rb && was_digit) {
1035 refresh_specified =
true;
1041 if (!bpp_specified && !yres_specified && !
cvt &&
1044 bpp_specified =
true;
1050 if (!yres_specified && was_digit) {
1052 yres_specified =
true;
1060 if (yres_specified ||
cvt || was_digit)
1065 if (yres_specified ||
cvt ||
rb || was_digit)
1070 if (
cvt || yres_specified || was_digit)
1075 if (
cvt || yres_specified || was_digit)
1080 if (yres_specified || bpp_specified || refresh_specified ||
1087 if (yres_specified || bpp_specified || refresh_specified ||
1098 if (yres_specified || bpp_specified || refresh_specified ||
1109 if (i < 0 && yres_specified) {
1112 if ((ch !=
NULL) && (*ch ==
'x'))
1113 res_specified =
true;
1116 }
else if (!yres_specified && was_digit) {
1123 "parse error at position %i in video mode '%s'\n",
1125 mode->specified =
false;
1129 if (res_specified) {
1130 mode->specified =
true;
1135 if (refresh_specified) {
1136 mode->refresh_specified =
true;
1137 mode->refresh = refresh;
1140 if (bpp_specified) {
1141 mode->bpp_specified =
true;
1147 mode->margins = margins;
1148 mode->force =
force;
1156 struct drm_cmdline_mode *
cmd)
1162 cmd->xres, cmd->yres,
1163 cmd->refresh_specified ? cmd->refresh : 60,
1164 cmd->rb, cmd->interlace,
1168 cmd->xres, cmd->yres,
1169 cmd->refresh_specified ? cmd->refresh : 60,