Rev 1123 | Rev 1221 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1123 | Rev 1179 | ||
---|---|---|---|
Line 6... | Line 6... | ||
6 | * |
6 | * |
7 | * Copyright © 1997-2003 by The XFree86 Project, Inc. |
7 | * Copyright © 1997-2003 by The XFree86 Project, Inc. |
8 | * Copyright © 2007 Dave Airlie |
8 | * Copyright © 2007 Dave Airlie |
9 | * Copyright © 2007-2008 Intel Corporation |
9 | * Copyright © 2007-2008 Intel Corporation |
10 | * Jesse Barnes |
10 | * Jesse Barnes |
- | 11 | * Copyright 2005-2006 Luc Verhaegen |
|
- | 12 | * Copyright (c) 2001, Andy Ritger aritger@nvidia.com |
|
11 | * |
13 | * |
12 | * Permission is hereby granted, free of charge, to any person obtaining a |
14 | * Permission is hereby granted, free of charge, to any person obtaining a |
13 | * copy of this software and associated documentation files (the "Software"), |
15 | * copy of this software and associated documentation files (the "Software"), |
14 | * to deal in the Software without restriction, including without limitation |
16 | * to deal in the Software without restriction, including without limitation |
15 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
17 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
Line 31... | Line 33... | ||
31 | * and author(s) shall not be used in advertising or otherwise to promote |
33 | * and author(s) shall not be used in advertising or otherwise to promote |
32 | * the sale, use or other dealings in this Software without prior written |
34 | * the sale, use or other dealings in this Software without prior written |
33 | * authorization from the copyright holder(s) and author(s). |
35 | * authorization from the copyright holder(s) and author(s). |
34 | */ |
36 | */ |
Line 35... | Line 37... | ||
35 | 37 | ||
36 | #include |
38 | #include |
37 | #include "drmP.h" |
39 | #include "drmP.h" |
38 | #include "drm.h" |
40 | #include "drm.h" |
Line 39... | Line -... | ||
39 | #include "drm_crtc.h" |
- | |
40 | 41 | #include "drm_crtc.h" |
|
41 | #define DRM_MODESET_DEBUG "drm_mode" |
42 | |
42 | /** |
43 | /** |
43 | * drm_mode_debug_printmodeline - debug print a mode |
44 | * drm_mode_debug_printmodeline - debug print a mode |
44 | * @dev: DRM device |
45 | * @dev: DRM device |
Line 49... | Line 50... | ||
49 | * |
50 | * |
50 | * Describe @mode using DRM_DEBUG. |
51 | * Describe @mode using DRM_DEBUG. |
51 | */ |
52 | */ |
52 | void drm_mode_debug_printmodeline(struct drm_display_mode *mode) |
53 | void drm_mode_debug_printmodeline(struct drm_display_mode *mode) |
53 | { |
54 | { |
54 | DRM_DEBUG_MODE(DRM_MODESET_DEBUG, |
- | |
55 | "Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", |
55 | DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d " |
- | 56 | "0x%x 0x%x\n", |
|
56 | mode->base.id, mode->name, mode->vrefresh, mode->clock, |
57 | mode->base.id, mode->name, mode->vrefresh, mode->clock, |
57 | mode->hdisplay, mode->hsync_start, |
58 | mode->hdisplay, mode->hsync_start, |
58 | mode->hsync_end, mode->htotal, |
59 | mode->hsync_end, mode->htotal, |
59 | mode->vdisplay, mode->vsync_start, |
60 | mode->vdisplay, mode->vsync_start, |
60 | mode->vsync_end, mode->vtotal, mode->type, mode->flags); |
61 | mode->vsync_end, mode->vtotal, mode->type, mode->flags); |
61 | } |
62 | } |
62 | EXPORT_SYMBOL(drm_mode_debug_printmodeline); |
63 | EXPORT_SYMBOL(drm_mode_debug_printmodeline); |
Line 63... | Line 64... | ||
63 | 64 | ||
- | 65 | /** |
|
- | 66 | * drm_cvt_mode -create a modeline based on CVT algorithm |
|
- | 67 | * @dev: DRM device |
|
- | 68 | * @hdisplay: hdisplay size |
|
- | 69 | * @vdisplay: vdisplay size |
|
- | 70 | * @vrefresh : vrefresh rate |
|
- | 71 | * @reduced : Whether the GTF calculation is simplified |
|
- | 72 | * @interlaced:Whether the interlace is supported |
|
- | 73 | * |
|
- | 74 | * LOCKING: |
|
- | 75 | * none. |
|
- | 76 | * |
|
- | 77 | * return the modeline based on CVT algorithm |
|
- | 78 | * |
|
- | 79 | * This function is called to generate the modeline based on CVT algorithm |
|
- | 80 | * according to the hdisplay, vdisplay, vrefresh. |
|
- | 81 | * It is based from the VESA(TM) Coordinated Video Timing Generator by |
|
- | 82 | * Graham Loveridge April 9, 2003 available at |
|
- | 83 | * http://www.vesa.org/public/CVT/CVTd6r1.xls |
|
- | 84 | * |
|
- | 85 | * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. |
|
- | 86 | * What I have done is to translate it by using integer calculation. |
|
- | 87 | */ |
|
- | 88 | #define HV_FACTOR 1000 |
|
- | 89 | struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, |
|
- | 90 | int vdisplay, int vrefresh, |
|
- | 91 | bool reduced, bool interlaced) |
|
- | 92 | { |
|
- | 93 | /* 1) top/bottom margin size (% of height) - default: 1.8, */ |
|
- | 94 | #define CVT_MARGIN_PERCENTAGE 18 |
|
- | 95 | /* 2) character cell horizontal granularity (pixels) - default 8 */ |
|
- | 96 | #define CVT_H_GRANULARITY 8 |
|
- | 97 | /* 3) Minimum vertical porch (lines) - default 3 */ |
|
- | 98 | #define CVT_MIN_V_PORCH 3 |
|
- | 99 | /* 4) Minimum number of vertical back porch lines - default 6 */ |
|
- | 100 | #define CVT_MIN_V_BPORCH 6 |
|
- | 101 | /* Pixel Clock step (kHz) */ |
|
- | 102 | #define CVT_CLOCK_STEP 250 |
|
- | 103 | struct drm_display_mode *drm_mode; |
|
- | 104 | bool margins = false; |
|
- | 105 | unsigned int vfieldrate, hperiod; |
|
- | 106 | int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; |
|
- | 107 | int interlace; |
|
- | 108 | ||
- | 109 | /* allocate the drm_display_mode structure. If failure, we will |
|
- | 110 | * return directly |
|
- | 111 | */ |
|
- | 112 | drm_mode = drm_mode_create(dev); |
|
- | 113 | if (!drm_mode) |
|
- | 114 | return NULL; |
|
- | 115 | ||
- | 116 | /* the CVT default refresh rate is 60Hz */ |
|
- | 117 | if (!vrefresh) |
|
- | 118 | vrefresh = 60; |
|
- | 119 | ||
- | 120 | /* the required field fresh rate */ |
|
- | 121 | if (interlaced) |
|
- | 122 | vfieldrate = vrefresh * 2; |
|
- | 123 | else |
|
- | 124 | vfieldrate = vrefresh; |
|
- | 125 | ||
- | 126 | /* horizontal pixels */ |
|
- | 127 | hdisplay_rnd = hdisplay - (hdisplay % CVT_H_GRANULARITY); |
|
- | 128 | ||
- | 129 | /* determine the left&right borders */ |
|
- | 130 | hmargin = 0; |
|
- | 131 | if (margins) { |
|
- | 132 | hmargin = hdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; |
|
- | 133 | hmargin -= hmargin % CVT_H_GRANULARITY; |
|
- | 134 | } |
|
- | 135 | /* find the total active pixels */ |
|
- | 136 | drm_mode->hdisplay = hdisplay_rnd + 2 * hmargin; |
|
- | 137 | ||
- | 138 | /* find the number of lines per field */ |
|
- | 139 | if (interlaced) |
|
- | 140 | vdisplay_rnd = vdisplay / 2; |
|
- | 141 | else |
|
- | 142 | vdisplay_rnd = vdisplay; |
|
- | 143 | ||
- | 144 | /* find the top & bottom borders */ |
|
- | 145 | vmargin = 0; |
|
- | 146 | if (margins) |
|
- | 147 | vmargin = vdisplay_rnd * CVT_MARGIN_PERCENTAGE / 1000; |
|
- | 148 | ||
- | 149 | drm_mode->vdisplay = vdisplay + 2 * vmargin; |
|
- | 150 | ||
- | 151 | /* Interlaced */ |
|
- | 152 | if (interlaced) |
|
- | 153 | interlace = 1; |
|
- | 154 | else |
|
- | 155 | interlace = 0; |
|
- | 156 | ||
- | 157 | /* Determine VSync Width from aspect ratio */ |
|
- | 158 | if (!(vdisplay % 3) && ((vdisplay * 4 / 3) == hdisplay)) |
|
- | 159 | vsync = 4; |
|
- | 160 | else if (!(vdisplay % 9) && ((vdisplay * 16 / 9) == hdisplay)) |
|
- | 161 | vsync = 5; |
|
- | 162 | else if (!(vdisplay % 10) && ((vdisplay * 16 / 10) == hdisplay)) |
|
- | 163 | vsync = 6; |
|
- | 164 | else if (!(vdisplay % 4) && ((vdisplay * 5 / 4) == hdisplay)) |
|
- | 165 | vsync = 7; |
|
- | 166 | else if (!(vdisplay % 9) && ((vdisplay * 15 / 9) == hdisplay)) |
|
- | 167 | vsync = 7; |
|
- | 168 | else /* custom */ |
|
- | 169 | vsync = 10; |
|
- | 170 | ||
- | 171 | if (!reduced) { |
|
- | 172 | /* simplify the GTF calculation */ |
|
- | 173 | /* 4) Minimum time of vertical sync + back porch interval (µs) |
|
- | 174 | * default 550.0 |
|
- | 175 | */ |
|
- | 176 | int tmp1, tmp2; |
|
- | 177 | #define CVT_MIN_VSYNC_BP 550 |
|
- | 178 | /* 3) Nominal HSync width (% of line period) - default 8 */ |
|
- | 179 | #define CVT_HSYNC_PERCENTAGE 8 |
|
- | 180 | unsigned int hblank_percentage; |
|
- | 181 | int vsyncandback_porch, vback_porch, hblank; |
|
- | 182 | ||
- | 183 | /* estimated the horizontal period */ |
|
- | 184 | tmp1 = HV_FACTOR * 1000000 - |
|
- | 185 | CVT_MIN_VSYNC_BP * HV_FACTOR * vfieldrate; |
|
- | 186 | tmp2 = (vdisplay_rnd + 2 * vmargin + CVT_MIN_V_PORCH) * 2 + |
|
- | 187 | interlace; |
|
- | 188 | hperiod = tmp1 * 2 / (tmp2 * vfieldrate); |
|
- | 189 | ||
- | 190 | tmp1 = CVT_MIN_VSYNC_BP * HV_FACTOR / hperiod + 1; |
|
- | 191 | /* 9. Find number of lines in sync + backporch */ |
|
- | 192 | if (tmp1 < (vsync + CVT_MIN_V_PORCH)) |
|
- | 193 | vsyncandback_porch = vsync + CVT_MIN_V_PORCH; |
|
- | 194 | else |
|
- | 195 | vsyncandback_porch = tmp1; |
|
- | 196 | /* 10. Find number of lines in back porch */ |
|
- | 197 | vback_porch = vsyncandback_porch - vsync; |
|
- | 198 | drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + |
|
- | 199 | vsyncandback_porch + CVT_MIN_V_PORCH; |
|
- | 200 | /* 5) Definition of Horizontal blanking time limitation */ |
|
- | 201 | /* Gradient (%/kHz) - default 600 */ |
|
- | 202 | #define CVT_M_FACTOR 600 |
|
- | 203 | /* Offset (%) - default 40 */ |
|
- | 204 | #define CVT_C_FACTOR 40 |
|
- | 205 | /* Blanking time scaling factor - default 128 */ |
|
- | 206 | #define CVT_K_FACTOR 128 |
|
- | 207 | /* Scaling factor weighting - default 20 */ |
|
- | 208 | #define CVT_J_FACTOR 20 |
|
- | 209 | #define CVT_M_PRIME (CVT_M_FACTOR * CVT_K_FACTOR / 256) |
|
- | 210 | #define CVT_C_PRIME ((CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ |
|
- | 211 | CVT_J_FACTOR) |
|
- | 212 | /* 12. Find ideal blanking duty cycle from formula */ |
|
- | 213 | hblank_percentage = CVT_C_PRIME * HV_FACTOR - CVT_M_PRIME * |
|
- | 214 | hperiod / 1000; |
|
- | 215 | /* 13. Blanking time */ |
|
- | 216 | if (hblank_percentage < 20 * HV_FACTOR) |
|
- | 217 | hblank_percentage = 20 * HV_FACTOR; |
|
- | 218 | hblank = drm_mode->hdisplay * hblank_percentage / |
|
- | 219 | (100 * HV_FACTOR - hblank_percentage); |
|
- | 220 | hblank -= hblank % (2 * CVT_H_GRANULARITY); |
|
- | 221 | /* 14. find the total pixes per line */ |
|
- | 222 | drm_mode->htotal = drm_mode->hdisplay + hblank; |
|
- | 223 | drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2; |
|
- | 224 | drm_mode->hsync_start = drm_mode->hsync_end - |
|
- | 225 | (drm_mode->htotal * CVT_HSYNC_PERCENTAGE) / 100; |
|
- | 226 | drm_mode->hsync_start += CVT_H_GRANULARITY - |
|
- | 227 | drm_mode->hsync_start % CVT_H_GRANULARITY; |
|
- | 228 | /* fill the Vsync values */ |
|
- | 229 | drm_mode->vsync_start = drm_mode->vdisplay + CVT_MIN_V_PORCH; |
|
- | 230 | drm_mode->vsync_end = drm_mode->vsync_start + vsync; |
|
- | 231 | } else { |
|
- | 232 | /* Reduced blanking */ |
|
- | 233 | /* Minimum vertical blanking interval time (µs)- default 460 */ |
|
- | 234 | #define CVT_RB_MIN_VBLANK 460 |
|
- | 235 | /* Fixed number of clocks for horizontal sync */ |
|
- | 236 | #define CVT_RB_H_SYNC 32 |
|
- | 237 | /* Fixed number of clocks for horizontal blanking */ |
|
- | 238 | #define CVT_RB_H_BLANK 160 |
|
- | 239 | /* Fixed number of lines for vertical front porch - default 3*/ |
|
- | 240 | #define CVT_RB_VFPORCH 3 |
|
- | 241 | int vbilines; |
|
- | 242 | int tmp1, tmp2; |
|
- | 243 | /* 8. Estimate Horizontal period. */ |
|
- | 244 | tmp1 = HV_FACTOR * 1000000 - |
|
- | 245 | CVT_RB_MIN_VBLANK * HV_FACTOR * vfieldrate; |
|
- | 246 | tmp2 = vdisplay_rnd + 2 * vmargin; |
|
- | 247 | hperiod = tmp1 / (tmp2 * vfieldrate); |
|
- | 248 | /* 9. Find number of lines in vertical blanking */ |
|
- | 249 | vbilines = CVT_RB_MIN_VBLANK * HV_FACTOR / hperiod + 1; |
|
- | 250 | /* 10. Check if vertical blanking is sufficient */ |
|
- | 251 | if (vbilines < (CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH)) |
|
- | 252 | vbilines = CVT_RB_VFPORCH + vsync + CVT_MIN_V_BPORCH; |
|
- | 253 | /* 11. Find total number of lines in vertical field */ |
|
- | 254 | drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines; |
|
- | 255 | /* 12. Find total number of pixels in a line */ |
|
- | 256 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
|
- | 257 | /* Fill in HSync values */ |
|
- | 258 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
|
- | 259 | drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; |
|
- | 260 | } |
|
- | 261 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
|
- | 262 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
|
- | 263 | drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; |
|
- | 264 | /* 18/16. Find actual vertical frame frequency */ |
|
- | 265 | /* ignore - just set the mode flag for interlaced */ |
|
- | 266 | if (interlaced) |
|
- | 267 | drm_mode->vtotal *= 2; |
|
- | 268 | /* Fill the mode line name */ |
|
- | 269 | drm_mode_set_name(drm_mode); |
|
- | 270 | if (reduced) |
|
- | 271 | drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC | |
|
- | 272 | DRM_MODE_FLAG_NVSYNC); |
|
- | 273 | else |
|
- | 274 | drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | |
|
- | 275 | DRM_MODE_FLAG_NHSYNC); |
|
- | 276 | if (interlaced) |
|
- | 277 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
|
- | 278 | ||
- | 279 | return drm_mode; |
|
- | 280 | } |
|
- | 281 | EXPORT_SYMBOL(drm_cvt_mode); |
|
- | 282 | ||
- | 283 | /** |
|
- | 284 | * drm_gtf_mode - create the modeline based on GTF algorithm |
|
- | 285 | * |
|
- | 286 | * @dev :drm device |
|
- | 287 | * @hdisplay :hdisplay size |
|
- | 288 | * @vdisplay :vdisplay size |
|
- | 289 | * @vrefresh :vrefresh rate. |
|
- | 290 | * @interlaced :whether the interlace is supported |
|
- | 291 | * @margins :whether the margin is supported |
|
- | 292 | * |
|
- | 293 | * LOCKING. |
|
- | 294 | * none. |
|
- | 295 | * |
|
- | 296 | * return the modeline based on GTF algorithm |
|
- | 297 | * |
|
- | 298 | * This function is to create the modeline based on the GTF algorithm. |
|
- | 299 | * Generalized Timing Formula is derived from: |
|
- | 300 | * GTF Spreadsheet by Andy Morrish (1/5/97) |
|
- | 301 | * available at http://www.vesa.org |
|
- | 302 | * |
|
- | 303 | * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. |
|
- | 304 | * What I have done is to translate it by using integer calculation. |
|
- | 305 | * I also refer to the function of fb_get_mode in the file of |
|
- | 306 | * drivers/video/fbmon.c |
|
- | 307 | */ |
|
- | 308 | struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, |
|
- | 309 | int vdisplay, int vrefresh, |
|
- | 310 | bool interlaced, int margins) |
|
- | 311 | { |
|
- | 312 | /* 1) top/bottom margin size (% of height) - default: 1.8, */ |
|
- | 313 | #define GTF_MARGIN_PERCENTAGE 18 |
|
- | 314 | /* 2) character cell horizontal granularity (pixels) - default 8 */ |
|
- | 315 | #define GTF_CELL_GRAN 8 |
|
- | 316 | /* 3) Minimum vertical porch (lines) - default 3 */ |
|
- | 317 | #define GTF_MIN_V_PORCH 1 |
|
- | 318 | /* width of vsync in lines */ |
|
- | 319 | #define V_SYNC_RQD 3 |
|
- | 320 | /* width of hsync as % of total line */ |
|
- | 321 | #define H_SYNC_PERCENT 8 |
|
- | 322 | /* min time of vsync + back porch (microsec) */ |
|
- | 323 | #define MIN_VSYNC_PLUS_BP 550 |
|
- | 324 | /* blanking formula gradient */ |
|
- | 325 | #define GTF_M 600 |
|
- | 326 | /* blanking formula offset */ |
|
- | 327 | #define GTF_C 40 |
|
- | 328 | /* blanking formula scaling factor */ |
|
- | 329 | #define GTF_K 128 |
|
- | 330 | /* blanking formula scaling factor */ |
|
- | 331 | #define GTF_J 20 |
|
- | 332 | /* C' and M' are part of the Blanking Duty Cycle computation */ |
|
- | 333 | #define GTF_C_PRIME (((GTF_C - GTF_J) * GTF_K / 256) + GTF_J) |
|
- | 334 | #define GTF_M_PRIME (GTF_K * GTF_M / 256) |
|
- | 335 | struct drm_display_mode *drm_mode; |
|
- | 336 | unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; |
|
- | 337 | int top_margin, bottom_margin; |
|
- | 338 | int interlace; |
|
- | 339 | unsigned int hfreq_est; |
|
- | 340 | int vsync_plus_bp, vback_porch; |
|
- | 341 | unsigned int vtotal_lines, vfieldrate_est, hperiod; |
|
- | 342 | unsigned int vfield_rate, vframe_rate; |
|
- | 343 | int left_margin, right_margin; |
|
- | 344 | unsigned int total_active_pixels, ideal_duty_cycle; |
|
- | 345 | unsigned int hblank, total_pixels, pixel_freq; |
|
- | 346 | int hsync, hfront_porch, vodd_front_porch_lines; |
|
- | 347 | unsigned int tmp1, tmp2; |
|
- | 348 | ||
- | 349 | drm_mode = drm_mode_create(dev); |
|
- | 350 | if (!drm_mode) |
|
- | 351 | return NULL; |
|
- | 352 | ||
- | 353 | /* 1. In order to give correct results, the number of horizontal |
|
- | 354 | * pixels requested is first processed to ensure that it is divisible |
|
- | 355 | * by the character size, by rounding it to the nearest character |
|
- | 356 | * cell boundary: |
|
- | 357 | */ |
|
- | 358 | hdisplay_rnd = (hdisplay + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; |
|
- | 359 | hdisplay_rnd = hdisplay_rnd * GTF_CELL_GRAN; |
|
- | 360 | ||
- | 361 | /* 2. If interlace is requested, the number of vertical lines assumed |
|
- | 362 | * by the calculation must be halved, as the computation calculates |
|
- | 363 | * the number of vertical lines per field. |
|
- | 364 | */ |
|
- | 365 | if (interlaced) |
|
- | 366 | vdisplay_rnd = vdisplay / 2; |
|
- | 367 | else |
|
- | 368 | vdisplay_rnd = vdisplay; |
|
- | 369 | ||
- | 370 | /* 3. Find the frame rate required: */ |
|
- | 371 | if (interlaced) |
|
- | 372 | vfieldrate_rqd = vrefresh * 2; |
|
- | 373 | else |
|
- | 374 | vfieldrate_rqd = vrefresh; |
|
- | 375 | ||
- | 376 | /* 4. Find number of lines in Top margin: */ |
|
- | 377 | top_margin = 0; |
|
- | 378 | if (margins) |
|
- | 379 | top_margin = (vdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / |
|
- | 380 | 1000; |
|
- | 381 | /* 5. Find number of lines in bottom margin: */ |
|
- | 382 | bottom_margin = top_margin; |
|
- | 383 | ||
- | 384 | /* 6. If interlace is required, then set variable interlace: */ |
|
- | 385 | if (interlaced) |
|
- | 386 | interlace = 1; |
|
- | 387 | else |
|
- | 388 | interlace = 0; |
|
- | 389 | ||
- | 390 | /* 7. Estimate the Horizontal frequency */ |
|
- | 391 | { |
|
- | 392 | tmp1 = (1000000 - MIN_VSYNC_PLUS_BP * vfieldrate_rqd) / 500; |
|
- | 393 | tmp2 = (vdisplay_rnd + 2 * top_margin + GTF_MIN_V_PORCH) * |
|
- | 394 | 2 + interlace; |
|
- | 395 | hfreq_est = (tmp2 * 1000 * vfieldrate_rqd) / tmp1; |
|
- | 396 | } |
|
- | 397 | ||
- | 398 | /* 8. Find the number of lines in V sync + back porch */ |
|
- | 399 | /* [V SYNC+BP] = RINT(([MIN VSYNC+BP] * hfreq_est / 1000000)) */ |
|
- | 400 | vsync_plus_bp = MIN_VSYNC_PLUS_BP * hfreq_est / 1000; |
|
- | 401 | vsync_plus_bp = (vsync_plus_bp + 500) / 1000; |
|
- | 402 | /* 9. Find the number of lines in V back porch alone: */ |
|
- | 403 | vback_porch = vsync_plus_bp - V_SYNC_RQD; |
|
- | 404 | /* 10. Find the total number of lines in Vertical field period: */ |
|
- | 405 | vtotal_lines = vdisplay_rnd + top_margin + bottom_margin + |
|
- | 406 | vsync_plus_bp + GTF_MIN_V_PORCH; |
|
- | 407 | /* 11. Estimate the Vertical field frequency: */ |
|
- | 408 | vfieldrate_est = hfreq_est / vtotal_lines; |
|
- | 409 | /* 12. Find the actual horizontal period: */ |
|
- | 410 | hperiod = 1000000 / (vfieldrate_rqd * vtotal_lines); |
|
- | 411 | ||
- | 412 | /* 13. Find the actual Vertical field frequency: */ |
|
- | 413 | vfield_rate = hfreq_est / vtotal_lines; |
|
- | 414 | /* 14. Find the Vertical frame frequency: */ |
|
- | 415 | if (interlaced) |
|
- | 416 | vframe_rate = vfield_rate / 2; |
|
- | 417 | else |
|
- | 418 | vframe_rate = vfield_rate; |
|
- | 419 | /* 15. Find number of pixels in left margin: */ |
|
- | 420 | if (margins) |
|
- | 421 | left_margin = (hdisplay_rnd * GTF_MARGIN_PERCENTAGE + 500) / |
|
- | 422 | 1000; |
|
- | 423 | else |
|
- | 424 | left_margin = 0; |
|
- | 425 | ||
- | 426 | /* 16.Find number of pixels in right margin: */ |
|
- | 427 | right_margin = left_margin; |
|
- | 428 | /* 17.Find total number of active pixels in image and left and right */ |
|
- | 429 | total_active_pixels = hdisplay_rnd + left_margin + right_margin; |
|
- | 430 | /* 18.Find the ideal blanking duty cycle from blanking duty cycle */ |
|
- | 431 | ideal_duty_cycle = GTF_C_PRIME * 1000 - |
|
- | 432 | (GTF_M_PRIME * 1000000 / hfreq_est); |
|
- | 433 | /* 19.Find the number of pixels in the blanking time to the nearest |
|
- | 434 | * double character cell: */ |
|
- | 435 | hblank = total_active_pixels * ideal_duty_cycle / |
|
- | 436 | (100000 - ideal_duty_cycle); |
|
- | 437 | hblank = (hblank + GTF_CELL_GRAN) / (2 * GTF_CELL_GRAN); |
|
- | 438 | hblank = hblank * 2 * GTF_CELL_GRAN; |
|
- | 439 | /* 20.Find total number of pixels: */ |
|
- | 440 | total_pixels = total_active_pixels + hblank; |
|
- | 441 | /* 21.Find pixel clock frequency: */ |
|
- | 442 | pixel_freq = total_pixels * hfreq_est / 1000; |
|
- | 443 | /* Stage 1 computations are now complete; I should really pass |
|
- | 444 | * the results to another function and do the Stage 2 computations, |
|
- | 445 | * but I only need a few more values so I'll just append the |
|
- | 446 | * computations here for now */ |
|
- | 447 | /* 17. Find the number of pixels in the horizontal sync period: */ |
|
- | 448 | hsync = H_SYNC_PERCENT * total_pixels / 100; |
|
- | 449 | hsync = (hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN; |
|
- | 450 | hsync = hsync * GTF_CELL_GRAN; |
|
- | 451 | /* 18. Find the number of pixels in horizontal front porch period */ |
|
- | 452 | hfront_porch = hblank / 2 - hsync; |
|
- | 453 | /* 36. Find the number of lines in the odd front porch period: */ |
|
- | 454 | vodd_front_porch_lines = GTF_MIN_V_PORCH ; |
|
- | 455 | ||
- | 456 | /* finally, pack the results in the mode struct */ |
|
- | 457 | drm_mode->hdisplay = hdisplay_rnd; |
|
- | 458 | drm_mode->hsync_start = hdisplay_rnd + hfront_porch; |
|
- | 459 | drm_mode->hsync_end = drm_mode->hsync_start + hsync; |
|
- | 460 | drm_mode->htotal = total_pixels; |
|
- | 461 | drm_mode->vdisplay = vdisplay_rnd; |
|
- | 462 | drm_mode->vsync_start = vdisplay_rnd + vodd_front_porch_lines; |
|
- | 463 | drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD; |
|
- | 464 | drm_mode->vtotal = vtotal_lines; |
|
- | 465 | ||
- | 466 | drm_mode->clock = pixel_freq; |
|
- | 467 | ||
- | 468 | drm_mode_set_name(drm_mode); |
|
- | 469 | drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; |
|
- | 470 | ||
- | 471 | if (interlaced) { |
|
- | 472 | drm_mode->vtotal *= 2; |
|
- | 473 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
|
- | 474 | } |
|
- | 475 | ||
- | 476 | return drm_mode; |
|
- | 477 | } |
|
- | 478 | EXPORT_SYMBOL(drm_gtf_mode); |
|
64 | /** |
479 | /** |
65 | * drm_mode_set_name - set the name on a mode |
480 | * drm_mode_set_name - set the name on a mode |
66 | * @mode: name will be set in this mode |
481 | * @mode: name will be set in this mode |
67 | * |
482 | * |
68 | * LOCKING: |
483 | * LOCKING: |
Line 149... | Line 564... | ||
149 | * Return @mode's vrefresh rate or calculate it if necessary. |
564 | * Return @mode's vrefresh rate or calculate it if necessary. |
150 | * |
565 | * |
151 | * FIXME: why is this needed? shouldn't vrefresh be set already? |
566 | * FIXME: why is this needed? shouldn't vrefresh be set already? |
152 | * |
567 | * |
153 | * RETURNS: |
568 | * RETURNS: |
154 | * Vertical refresh rate of @mode x 1000. For precision reasons. |
569 | * Vertical refresh rate. It will be the result of actual value plus 0.5. |
- | 570 | * If it is 70.288, it will return 70Hz. |
|
- | 571 | * If it is 59.6, it will return 60Hz. |
|
155 | */ |
572 | */ |
156 | int drm_mode_vrefresh(struct drm_display_mode *mode) |
573 | int drm_mode_vrefresh(struct drm_display_mode *mode) |
157 | { |
574 | { |
158 | int refresh = 0; |
575 | int refresh = 0; |
159 | unsigned int calc_val; |
576 | unsigned int calc_val; |
Line 160... | Line 577... | ||
160 | 577 | ||
161 | if (mode->vrefresh > 0) |
578 | if (mode->vrefresh > 0) |
162 | refresh = mode->vrefresh; |
579 | refresh = mode->vrefresh; |
- | 580 | else if (mode->htotal > 0 && mode->vtotal > 0) { |
|
- | 581 | int vtotal; |
|
163 | else if (mode->htotal > 0 && mode->vtotal > 0) { |
582 | vtotal = mode->vtotal; |
164 | /* work out vrefresh the value will be x1000 */ |
583 | /* work out vrefresh the value will be x1000 */ |
165 | calc_val = (mode->clock * 1000); |
- | |
166 | 584 | calc_val = (mode->clock * 1000); |
|
167 | calc_val /= mode->htotal; |
- | |
168 | calc_val *= 1000; |
585 | calc_val /= mode->htotal; |
Line 169... | Line -... | ||
169 | calc_val /= mode->vtotal; |
- | |
170 | 586 | refresh = (calc_val + vtotal / 2) / vtotal; |
|
171 | refresh = calc_val; |
587 | |
172 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
588 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
173 | refresh *= 2; |
589 | refresh *= 2; |
174 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
590 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
Line 401... | Line 817... | ||
401 | list_for_each_entry_safe(mode, t, mode_list, head) { |
817 | list_for_each_entry_safe(mode, t, mode_list, head) { |
402 | if (mode->status != MODE_OK) { |
818 | if (mode->status != MODE_OK) { |
403 | list_del(&mode->head); |
819 | list_del(&mode->head); |
404 | if (verbose) { |
820 | if (verbose) { |
405 | drm_mode_debug_printmodeline(mode); |
821 | drm_mode_debug_printmodeline(mode); |
406 | DRM_DEBUG_MODE(DRM_MODESET_DEBUG, |
- | |
407 | "Not using %s mode %d\n", |
822 | DRM_DEBUG_KMS("Not using %s mode %d\n", |
408 | mode->name, mode->status); |
823 | mode->name, mode->status); |
409 | } |
824 | } |
410 | drm_mode_destroy(dev, mode); |
825 | drm_mode_destroy(dev, mode); |
411 | } |
826 | } |
412 | } |
827 | } |
Line 564... | Line 979... | ||
564 | list_for_each_entry(mode, &connector->modes, head) { |
979 | list_for_each_entry(mode, &connector->modes, head) { |
565 | if (drm_mode_equal(pmode, mode)) { |
980 | if (drm_mode_equal(pmode, mode)) { |
566 | found_it = 1; |
981 | found_it = 1; |
567 | /* if equal delete the probed mode */ |
982 | /* if equal delete the probed mode */ |
568 | mode->status = pmode->status; |
983 | mode->status = pmode->status; |
- | 984 | /* Merge type bits together */ |
|
- | 985 | mode->type |= pmode->type; |
|
569 | list_del(&pmode->head); |
986 | list_del(&pmode->head); |
570 | drm_mode_destroy(connector->dev, pmode); |
987 | drm_mode_destroy(connector->dev, pmode); |
571 | break; |
988 | break; |
572 | } |
989 | } |
573 | } |
990 | } |