diff options
Diffstat (limited to 'drivers/gpu/drm/drm_modes.c')
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 105 |
1 files changed, 69 insertions, 36 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 76d63394c776..f1f473ea97d3 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -258,8 +258,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
258 | drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; | 258 | drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; |
259 | /* 18/16. Find actual vertical frame frequency */ | 259 | /* 18/16. Find actual vertical frame frequency */ |
260 | /* ignore - just set the mode flag for interlaced */ | 260 | /* ignore - just set the mode flag for interlaced */ |
261 | if (interlaced) | 261 | if (interlaced) { |
262 | drm_mode->vtotal *= 2; | 262 | drm_mode->vtotal *= 2; |
263 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
264 | } | ||
263 | /* Fill the mode line name */ | 265 | /* Fill the mode line name */ |
264 | drm_mode_set_name(drm_mode); | 266 | drm_mode_set_name(drm_mode); |
265 | if (reduced) | 267 | if (reduced) |
@@ -268,43 +270,35 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
268 | else | 270 | else |
269 | drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | | 271 | drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | |
270 | DRM_MODE_FLAG_NHSYNC); | 272 | DRM_MODE_FLAG_NHSYNC); |
271 | if (interlaced) | ||
272 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; | ||
273 | 273 | ||
274 | return drm_mode; | 274 | return drm_mode; |
275 | } | 275 | } |
276 | EXPORT_SYMBOL(drm_cvt_mode); | 276 | EXPORT_SYMBOL(drm_cvt_mode); |
277 | 277 | ||
278 | /** | 278 | /** |
279 | * drm_gtf_mode - create the modeline based on GTF algorithm | 279 | * drm_gtf_mode_complex - create the modeline based on full GTF algorithm |
280 | * | 280 | * |
281 | * @dev :drm device | 281 | * @dev :drm device |
282 | * @hdisplay :hdisplay size | 282 | * @hdisplay :hdisplay size |
283 | * @vdisplay :vdisplay size | 283 | * @vdisplay :vdisplay size |
284 | * @vrefresh :vrefresh rate. | 284 | * @vrefresh :vrefresh rate. |
285 | * @interlaced :whether the interlace is supported | 285 | * @interlaced :whether the interlace is supported |
286 | * @margins :whether the margin is supported | 286 | * @margins :desired margin size |
287 | * @GTF_[MCKJ] :extended GTF formula parameters | ||
287 | * | 288 | * |
288 | * LOCKING. | 289 | * LOCKING. |
289 | * none. | 290 | * none. |
290 | * | 291 | * |
291 | * return the modeline based on GTF algorithm | 292 | * return the modeline based on full GTF algorithm. |
292 | * | ||
293 | * This function is to create the modeline based on the GTF algorithm. | ||
294 | * Generalized Timing Formula is derived from: | ||
295 | * GTF Spreadsheet by Andy Morrish (1/5/97) | ||
296 | * available at http://www.vesa.org | ||
297 | * | 293 | * |
298 | * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. | 294 | * GTF feature blocks specify C and J in multiples of 0.5, so we pass them |
299 | * What I have done is to translate it by using integer calculation. | 295 | * in here multiplied by two. For a C of 40, pass in 80. |
300 | * I also refer to the function of fb_get_mode in the file of | ||
301 | * drivers/video/fbmon.c | ||
302 | */ | 296 | */ |
303 | struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, | 297 | struct drm_display_mode * |
304 | int vdisplay, int vrefresh, | 298 | drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay, |
305 | bool interlaced, int margins) | 299 | int vrefresh, bool interlaced, int margins, |
306 | { | 300 | int GTF_M, int GTF_2C, int GTF_K, int GTF_2J) |
307 | /* 1) top/bottom margin size (% of height) - default: 1.8, */ | 301 | { /* 1) top/bottom margin size (% of height) - default: 1.8, */ |
308 | #define GTF_MARGIN_PERCENTAGE 18 | 302 | #define GTF_MARGIN_PERCENTAGE 18 |
309 | /* 2) character cell horizontal granularity (pixels) - default 8 */ | 303 | /* 2) character cell horizontal granularity (pixels) - default 8 */ |
310 | #define GTF_CELL_GRAN 8 | 304 | #define GTF_CELL_GRAN 8 |
@@ -316,17 +310,9 @@ struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, | |||
316 | #define H_SYNC_PERCENT 8 | 310 | #define H_SYNC_PERCENT 8 |
317 | /* min time of vsync + back porch (microsec) */ | 311 | /* min time of vsync + back porch (microsec) */ |
318 | #define MIN_VSYNC_PLUS_BP 550 | 312 | #define MIN_VSYNC_PLUS_BP 550 |
319 | /* blanking formula gradient */ | ||
320 | #define GTF_M 600 | ||
321 | /* blanking formula offset */ | ||
322 | #define GTF_C 40 | ||
323 | /* blanking formula scaling factor */ | ||
324 | #define GTF_K 128 | ||
325 | /* blanking formula scaling factor */ | ||
326 | #define GTF_J 20 | ||
327 | /* C' and M' are part of the Blanking Duty Cycle computation */ | 313 | /* C' and M' are part of the Blanking Duty Cycle computation */ |
328 | #define GTF_C_PRIME (((GTF_C - GTF_J) * GTF_K / 256) + GTF_J) | 314 | #define GTF_C_PRIME ((((GTF_2C - GTF_2J) * GTF_K / 256) + GTF_2J) / 2) |
329 | #define GTF_M_PRIME (GTF_K * GTF_M / 256) | 315 | #define GTF_M_PRIME (GTF_K * GTF_M / 256) |
330 | struct drm_display_mode *drm_mode; | 316 | struct drm_display_mode *drm_mode; |
331 | unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; | 317 | unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; |
332 | int top_margin, bottom_margin; | 318 | int top_margin, bottom_margin; |
@@ -460,17 +446,61 @@ struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, | |||
460 | 446 | ||
461 | drm_mode->clock = pixel_freq; | 447 | drm_mode->clock = pixel_freq; |
462 | 448 | ||
463 | drm_mode_set_name(drm_mode); | ||
464 | drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; | ||
465 | |||
466 | if (interlaced) { | 449 | if (interlaced) { |
467 | drm_mode->vtotal *= 2; | 450 | drm_mode->vtotal *= 2; |
468 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; | 451 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
469 | } | 452 | } |
470 | 453 | ||
454 | drm_mode_set_name(drm_mode); | ||
455 | if (GTF_M == 600 && GTF_2C == 80 && GTF_K == 128 && GTF_2J == 40) | ||
456 | drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; | ||
457 | else | ||
458 | drm_mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC; | ||
459 | |||
471 | return drm_mode; | 460 | return drm_mode; |
472 | } | 461 | } |
462 | EXPORT_SYMBOL(drm_gtf_mode_complex); | ||
463 | |||
464 | /** | ||
465 | * drm_gtf_mode - create the modeline based on GTF algorithm | ||
466 | * | ||
467 | * @dev :drm device | ||
468 | * @hdisplay :hdisplay size | ||
469 | * @vdisplay :vdisplay size | ||
470 | * @vrefresh :vrefresh rate. | ||
471 | * @interlaced :whether the interlace is supported | ||
472 | * @margins :whether the margin is supported | ||
473 | * | ||
474 | * LOCKING. | ||
475 | * none. | ||
476 | * | ||
477 | * return the modeline based on GTF algorithm | ||
478 | * | ||
479 | * This function is to create the modeline based on the GTF algorithm. | ||
480 | * Generalized Timing Formula is derived from: | ||
481 | * GTF Spreadsheet by Andy Morrish (1/5/97) | ||
482 | * available at http://www.vesa.org | ||
483 | * | ||
484 | * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. | ||
485 | * What I have done is to translate it by using integer calculation. | ||
486 | * I also refer to the function of fb_get_mode in the file of | ||
487 | * drivers/video/fbmon.c | ||
488 | * | ||
489 | * Standard GTF parameters: | ||
490 | * M = 600 | ||
491 | * C = 40 | ||
492 | * K = 128 | ||
493 | * J = 20 | ||
494 | */ | ||
495 | struct drm_display_mode * | ||
496 | drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, | ||
497 | bool lace, int margins) | ||
498 | { | ||
499 | return drm_gtf_mode_complex(dev, hdisplay, vdisplay, vrefresh, lace, | ||
500 | margins, 600, 40 * 2, 128, 20 * 2); | ||
501 | } | ||
473 | EXPORT_SYMBOL(drm_gtf_mode); | 502 | EXPORT_SYMBOL(drm_gtf_mode); |
503 | |||
474 | /** | 504 | /** |
475 | * drm_mode_set_name - set the name on a mode | 505 | * drm_mode_set_name - set the name on a mode |
476 | * @mode: name will be set in this mode | 506 | * @mode: name will be set in this mode |
@@ -482,8 +512,11 @@ EXPORT_SYMBOL(drm_gtf_mode); | |||
482 | */ | 512 | */ |
483 | void drm_mode_set_name(struct drm_display_mode *mode) | 513 | void drm_mode_set_name(struct drm_display_mode *mode) |
484 | { | 514 | { |
485 | snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode->hdisplay, | 515 | bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); |
486 | mode->vdisplay); | 516 | |
517 | snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d%s", | ||
518 | mode->hdisplay, mode->vdisplay, | ||
519 | interlaced ? "i" : ""); | ||
487 | } | 520 | } |
488 | EXPORT_SYMBOL(drm_mode_set_name); | 521 | EXPORT_SYMBOL(drm_mode_set_name); |
489 | 522 | ||