Rev 1404 | Rev 3192 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1404 | Rev 1963 | ||
---|---|---|---|
Line 74... | Line 74... | ||
74 | * |
74 | * |
75 | * This function is called to generate the modeline based on CVT algorithm |
75 | * This function is called to generate the modeline based on CVT algorithm |
76 | * according to the hdisplay, vdisplay, vrefresh. |
76 | * according to the hdisplay, vdisplay, vrefresh. |
77 | * It is based from the VESA(TM) Coordinated Video Timing Generator by |
77 | * It is based from the VESA(TM) Coordinated Video Timing Generator by |
78 | * Graham Loveridge April 9, 2003 available at |
78 | * Graham Loveridge April 9, 2003 available at |
79 | * http://www.vesa.org/public/CVT/CVTd6r1.xls |
79 | * http://www.elo.utfsm.cl/~elo212/docs/CVTd6r1.xls |
80 | * |
80 | * |
81 | * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. |
81 | * And it is copied from xf86CVTmode in xserver/hw/xfree86/modes/xf86cvt.c. |
82 | * What I have done is to translate it by using integer calculation. |
82 | * What I have done is to translate it by using integer calculation. |
83 | */ |
83 | */ |
84 | #define HV_FACTOR 1000 |
84 | #define HV_FACTOR 1000 |
Line 249... | Line 249... | ||
249 | drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines; |
249 | drm_mode->vtotal = vdisplay_rnd + 2 * vmargin + vbilines; |
250 | /* 12. Find total number of pixels in a line */ |
250 | /* 12. Find total number of pixels in a line */ |
251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
252 | /* Fill in HSync values */ |
252 | /* Fill in HSync values */ |
253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
254 | drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; |
254 | drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC; |
- | 255 | /* Fill in VSync values */ |
|
- | 256 | drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH; |
|
- | 257 | drm_mode->vsync_end = drm_mode->vsync_start + vsync; |
|
255 | } |
258 | } |
256 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
259 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
257 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
260 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
258 | drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; |
261 | drm_mode->clock -= drm_mode->clock % CVT_CLOCK_STEP; |
259 | /* 18/16. Find actual vertical frame frequency */ |
262 | /* 18/16. Find actual vertical frame frequency */ |
260 | /* ignore - just set the mode flag for interlaced */ |
263 | /* ignore - just set the mode flag for interlaced */ |
261 | if (interlaced) |
264 | if (interlaced) { |
262 | drm_mode->vtotal *= 2; |
265 | drm_mode->vtotal *= 2; |
- | 266 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
|
- | 267 | } |
|
263 | /* Fill the mode line name */ |
268 | /* Fill the mode line name */ |
264 | drm_mode_set_name(drm_mode); |
269 | drm_mode_set_name(drm_mode); |
265 | if (reduced) |
270 | if (reduced) |
266 | drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC | |
271 | drm_mode->flags |= (DRM_MODE_FLAG_PHSYNC | |
267 | DRM_MODE_FLAG_NVSYNC); |
272 | DRM_MODE_FLAG_NVSYNC); |
268 | else |
273 | else |
269 | drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | |
274 | drm_mode->flags |= (DRM_MODE_FLAG_PVSYNC | |
270 | DRM_MODE_FLAG_NHSYNC); |
275 | DRM_MODE_FLAG_NHSYNC); |
271 | if (interlaced) |
- | |
272 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
- | |
Line 273... | Line 276... | ||
273 | 276 | ||
274 | return drm_mode; |
277 | return drm_mode; |
275 | } |
278 | } |
Line 276... | Line 279... | ||
276 | EXPORT_SYMBOL(drm_cvt_mode); |
279 | EXPORT_SYMBOL(drm_cvt_mode); |
277 | 280 | ||
278 | /** |
281 | /** |
279 | * drm_gtf_mode - create the modeline based on GTF algorithm |
282 | * drm_gtf_mode_complex - create the modeline based on full GTF algorithm |
280 | * |
283 | * |
281 | * @dev :drm device |
284 | * @dev :drm device |
282 | * @hdisplay :hdisplay size |
285 | * @hdisplay :hdisplay size |
283 | * @vdisplay :vdisplay size |
286 | * @vdisplay :vdisplay size |
284 | * @vrefresh :vrefresh rate. |
287 | * @vrefresh :vrefresh rate. |
- | 288 | * @interlaced :whether the interlace is supported |
|
285 | * @interlaced :whether the interlace is supported |
289 | * @margins :desired margin size |
286 | * @margins :whether the margin is supported |
290 | * @GTF_[MCKJ] :extended GTF formula parameters |
287 | * |
291 | * |
288 | * LOCKING. |
292 | * LOCKING. |
289 | * none. |
293 | * none. |
290 | * |
- | |
291 | * return the modeline based on 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) |
294 | * |
296 | * available at http://www.vesa.org |
- | |
297 | * |
295 | * return the modeline based on full GTF algorithm. |
298 | * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. |
296 | * |
299 | * What I have done is to translate it by using integer calculation. |
- | |
300 | * I also refer to the function of fb_get_mode in the file of |
297 | * GTF feature blocks specify C and J in multiples of 0.5, so we pass them |
- | 298 | * in here multiplied by two. For a C of 40, pass in 80. |
|
301 | * drivers/video/fbmon.c |
299 | */ |
302 | */ |
300 | struct drm_display_mode * |
303 | struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, int hdisplay, |
301 | drm_gtf_mode_complex(struct drm_device *dev, int hdisplay, int vdisplay, |
304 | int vdisplay, int vrefresh, |
- | |
305 | bool interlaced, int margins) |
302 | int vrefresh, bool interlaced, int margins, |
306 | { |
303 | int GTF_M, int GTF_2C, int GTF_K, int GTF_2J) |
307 | /* 1) top/bottom margin size (% of height) - default: 1.8, */ |
304 | { /* 1) top/bottom margin size (% of height) - default: 1.8, */ |
308 | #define GTF_MARGIN_PERCENTAGE 18 |
305 | #define GTF_MARGIN_PERCENTAGE 18 |
309 | /* 2) character cell horizontal granularity (pixels) - default 8 */ |
306 | /* 2) character cell horizontal granularity (pixels) - default 8 */ |
310 | #define GTF_CELL_GRAN 8 |
307 | #define GTF_CELL_GRAN 8 |
Line 314... | Line 311... | ||
314 | #define V_SYNC_RQD 3 |
311 | #define V_SYNC_RQD 3 |
315 | /* width of hsync as % of total line */ |
312 | /* width of hsync as % of total line */ |
316 | #define H_SYNC_PERCENT 8 |
313 | #define H_SYNC_PERCENT 8 |
317 | /* min time of vsync + back porch (microsec) */ |
314 | /* min time of vsync + back porch (microsec) */ |
318 | #define MIN_VSYNC_PLUS_BP 550 |
315 | #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 */ |
316 | /* 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) |
317 | #define GTF_C_PRIME ((((GTF_2C - GTF_2J) * GTF_K / 256) + GTF_2J) / 2) |
329 | #define GTF_M_PRIME (GTF_K * GTF_M / 256) |
318 | #define GTF_M_PRIME (GTF_K * GTF_M / 256) |
330 | struct drm_display_mode *drm_mode; |
319 | struct drm_display_mode *drm_mode; |
331 | unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; |
320 | unsigned int hdisplay_rnd, vdisplay_rnd, vfieldrate_rqd; |
332 | int top_margin, bottom_margin; |
321 | int top_margin, bottom_margin; |
333 | int interlace; |
322 | int interlace; |
Line 458... | Line 447... | ||
458 | drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD; |
447 | drm_mode->vsync_end = drm_mode->vsync_start + V_SYNC_RQD; |
459 | drm_mode->vtotal = vtotal_lines; |
448 | drm_mode->vtotal = vtotal_lines; |
Line 460... | Line 449... | ||
460 | 449 | ||
Line 461... | Line -... | ||
461 | drm_mode->clock = pixel_freq; |
- | |
462 | - | ||
463 | drm_mode_set_name(drm_mode); |
- | |
464 | drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; |
450 | drm_mode->clock = pixel_freq; |
465 | 451 | ||
466 | if (interlaced) { |
452 | if (interlaced) { |
467 | drm_mode->vtotal *= 2; |
453 | drm_mode->vtotal *= 2; |
Line -... | Line 454... | ||
- | 454 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
|
- | 455 | } |
|
- | 456 | ||
- | 457 | drm_mode_set_name(drm_mode); |
|
- | 458 | if (GTF_M == 600 && GTF_2C == 80 && GTF_K == 128 && GTF_2J == 40) |
|
- | 459 | drm_mode->flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC; |
|
468 | drm_mode->flags |= DRM_MODE_FLAG_INTERLACE; |
460 | else |
469 | } |
461 | drm_mode->flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC; |
- | 462 | ||
- | 463 | return drm_mode; |
|
- | 464 | } |
|
- | 465 | EXPORT_SYMBOL(drm_gtf_mode_complex); |
|
- | 466 | ||
- | 467 | /** |
|
- | 468 | * drm_gtf_mode - create the modeline based on GTF algorithm |
|
- | 469 | * |
|
- | 470 | * @dev :drm device |
|
- | 471 | * @hdisplay :hdisplay size |
|
- | 472 | * @vdisplay :vdisplay size |
|
- | 473 | * @vrefresh :vrefresh rate. |
|
- | 474 | * @interlaced :whether the interlace is supported |
|
- | 475 | * @margins :whether the margin is supported |
|
- | 476 | * |
|
- | 477 | * LOCKING. |
|
- | 478 | * none. |
|
- | 479 | * |
|
- | 480 | * return the modeline based on GTF algorithm |
|
- | 481 | * |
|
- | 482 | * This function is to create the modeline based on the GTF algorithm. |
|
- | 483 | * Generalized Timing Formula is derived from: |
|
- | 484 | * GTF Spreadsheet by Andy Morrish (1/5/97) |
|
- | 485 | * available at http://www.vesa.org |
|
- | 486 | * |
|
- | 487 | * And it is copied from the file of xserver/hw/xfree86/modes/xf86gtf.c. |
|
- | 488 | * What I have done is to translate it by using integer calculation. |
|
- | 489 | * I also refer to the function of fb_get_mode in the file of |
|
- | 490 | * drivers/video/fbmon.c |
|
- | 491 | * |
|
- | 492 | * Standard GTF parameters: |
|
- | 493 | * M = 600 |
|
- | 494 | * C = 40 |
|
- | 495 | * K = 128 |
|
- | 496 | * J = 20 |
|
- | 497 | */ |
|
- | 498 | struct drm_display_mode * |
|
- | 499 | drm_gtf_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, |
|
- | 500 | bool lace, int margins) |
|
- | 501 | { |
|
470 | 502 | return drm_gtf_mode_complex(dev, hdisplay, vdisplay, vrefresh, lace, |
|
- | 503 | margins, 600, 40 * 2, 128, 20 * 2); |
|
471 | return drm_mode; |
504 | } |
472 | } |
505 | EXPORT_SYMBOL(drm_gtf_mode); |
473 | EXPORT_SYMBOL(drm_gtf_mode); |
506 | |
474 | /** |
507 | /** |
475 | * drm_mode_set_name - set the name on a mode |
508 | * drm_mode_set_name - set the name on a mode |
Line 480... | Line 513... | ||
480 | * |
513 | * |
481 | * Set the name of @mode to a standard format. |
514 | * Set the name of @mode to a standard format. |
482 | */ |
515 | */ |
483 | void drm_mode_set_name(struct drm_display_mode *mode) |
516 | void drm_mode_set_name(struct drm_display_mode *mode) |
484 | { |
517 | { |
- | 518 | bool interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); |
|
- | 519 | ||
485 | snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d", mode->hdisplay, |
520 | snprintf(mode->name, DRM_DISPLAY_MODE_LEN, "%dx%d%s", |
486 | mode->vdisplay); |
521 | mode->hdisplay, mode->vdisplay, |
- | 522 | interlaced ? "i" : ""); |
|
487 | } |
523 | } |
488 | EXPORT_SYMBOL(drm_mode_set_name); |
524 | EXPORT_SYMBOL(drm_mode_set_name); |
Line 489... | Line 525... | ||
489 | 525 | ||
490 | /** |
526 | /** |
Line 555... | Line 591... | ||
555 | * LOCKING: |
591 | * LOCKING: |
556 | * None. |
592 | * None. |
557 | * |
593 | * |
558 | * Return @modes's hsync rate in kHz, rounded to the nearest int. |
594 | * Return @modes's hsync rate in kHz, rounded to the nearest int. |
559 | */ |
595 | */ |
560 | int drm_mode_hsync(struct drm_display_mode *mode) |
596 | int drm_mode_hsync(const struct drm_display_mode *mode) |
561 | { |
597 | { |
562 | unsigned int calc_val; |
598 | unsigned int calc_val; |
Line 563... | Line 599... | ||
563 | 599 | ||
564 | if (mode->hsync) |
600 | if (mode->hsync) |
Line 589... | Line 625... | ||
589 | * RETURNS: |
625 | * RETURNS: |
590 | * Vertical refresh rate. It will be the result of actual value plus 0.5. |
626 | * Vertical refresh rate. It will be the result of actual value plus 0.5. |
591 | * If it is 70.288, it will return 70Hz. |
627 | * If it is 70.288, it will return 70Hz. |
592 | * If it is 59.6, it will return 60Hz. |
628 | * If it is 59.6, it will return 60Hz. |
593 | */ |
629 | */ |
594 | int drm_mode_vrefresh(struct drm_display_mode *mode) |
630 | int drm_mode_vrefresh(const struct drm_display_mode *mode) |
595 | { |
631 | { |
596 | int refresh = 0; |
632 | int refresh = 0; |
597 | unsigned int calc_val; |
633 | unsigned int calc_val; |
Line 598... | Line 634... | ||
598 | 634 | ||
Line 687... | Line 723... | ||
687 | * |
723 | * |
688 | * Just allocate a new mode, copy the existing mode into it, and return |
724 | * Just allocate a new mode, copy the existing mode into it, and return |
689 | * a pointer to it. Used to create new instances of established modes. |
725 | * a pointer to it. Used to create new instances of established modes. |
690 | */ |
726 | */ |
691 | struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, |
727 | struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, |
692 | struct drm_display_mode *mode) |
728 | const struct drm_display_mode *mode) |
693 | { |
729 | { |
694 | struct drm_display_mode *nmode; |
730 | struct drm_display_mode *nmode; |
695 | int new_id; |
731 | int new_id; |
Line 696... | Line 732... | ||
696 | 732 |